Skip to content

Commit

Permalink
Merge pull request #5 from jucasoliveira/change_to_nodejs
Browse files Browse the repository at this point in the history
add changes
  • Loading branch information
jucasoliveira authored Jan 5, 2023
2 parents b73a8e1 + 4584414 commit e4e5893
Show file tree
Hide file tree
Showing 6 changed files with 2,439 additions and 161 deletions.
15 changes: 15 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": "eslint:recommended",
"overrides": [
],
"parserOptions": {
"ecmaVersion": "latest"
},
"rules": {
}
}
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ Get GPT like chatGPT on your terminal

![Screenshot 2023-01-05 at 09 24 10](https://user-images.githubusercontent.com/11979969/210746185-69722c94-b073-4863-82bc-b662236c8305.png)


# Get Started

```
npm install
npx terminalgpt
```

or
# Run

```
yarn
```bash
npx terminalgpt chat
```

# Run
# Changing engine and temperature

```bash
node ./bin/terminalGPT chat --engine "text-davinci-002" --temperature 0.7
```
npx terminalgpt chat --engine "text-davinci-002" --temperature 0.7
```
170 changes: 170 additions & 0 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#!/usr/bin/env node

const { Configuration, OpenAIApi } = require("openai");
const commander = require("commander");
const prompts = require("prompts");
const chalk = require("chalk");
const gradient = require("gradient-string");
const fs = require("fs");
const process = require("process");
const ora = require("ora");
const crypto = require("crypto");

const algorithm = "aes-256-cbc";
const secretKey = "terminalGPT";

const encrypt = (text) => {
const iv = crypto.randomBytes(16);
const key = crypto.scryptSync(secretKey, "salt", 32);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(text);

encrypted = Buffer.concat([encrypted, cipher.final()]);
return iv.toString("hex") + ":" + encrypted.toString("hex");
};

const decrypt = (text) => {
const textParts = text.split(":");
const iv = Buffer.from(textParts.shift(), "hex");
const encryptedText = Buffer.from(textParts.join(":"), "hex");
const key = crypto.scryptSync(secretKey, "salt", 32);
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
};

const saveApiKey = (apiKey) => {
fs.writeFileSync("./apiKey.txt", apiKey);
};

const getApiKey = () => {
if (fs.existsSync("./apiKey.txt")) {
const getEncryptedScript = fs.readFileSync("./apiKey.txt", "utf8");
const decryptedScript = decrypt(getEncryptedScript);
return decryptedScript;
}
};

const apiKeyPrompt = async () => {
let apiKey = getApiKey();
if (!apiKey) {
const response = await prompts({
type: "password",
name: "apiKey",
message: "Enter your OpenAI API key:",
validate: (value) => {
return value !== "";
},
});

apiKey = encrypt(response.apiKey);
saveApiKey(apiKey);
}

return apiKey;
};

const intro = function () {
const usageText = `
${gradient(
"cyan",
"pink"
)("****************")} Welcome to ${chalk.greenBright(
"terminalGPT"
)} ${gradient("cyan", "pink")("****************")}
${gradient("orange", "yellow").multiline(
[" __", "<(o )___", " ( ._> /", " `---'"].join("\n")
)}
${chalk.yellowBright("usage:")}
TerminalGPT will ask you to add your OpenAI API key. Don't worry, it's saves on your machine locally.
Terminal will prompt you to enter a message. Type your message and press enter.
Terminal will then prompt you to enter a response. Type your response and press enter.
To exit, type "${chalk.redBright("exit")}" and press enter.
`;

console.log(usageText);
};

const generateResponse = async (apiKey, prompt, options, response) => {
const configuration = new Configuration({
apiKey,
});
const openai = new OpenAIApi(configuration);
const spinner = ora("Thinking...").start();
const request = await openai
.createCompletion({
model: options.engine || "text-davinci-002",
prompt: response.value,
max_tokens: 2048,
temperature: parseInt(options.temperature) || 0.5,
})
.then((response) => {
spinner.stop();
return response;
})
.catch((err) => {
console.error(`${chalk.red("Something went wront")} ${err}`);
});
if (!request.data?.choices?.[0].text) {
return console.error(`${chalk.red("Something went wront")}`);
}

// map all choices to text
const getText = request.data.choices.map((choice) => choice.text);

console.log(`${chalk.cyan("GPT-3: ")}`);
// console log each character of the text with a delay and then call prompt when it finished
let i = 0;
const interval = setInterval(() => {
if (i < getText[0].length) {
process.stdout.write(getText[0][i]);
i++;
} else {
clearInterval(interval);
console.log("\n");
prompt();
}
}, 10);
};

commander
.command("chat")
.option("-e, --engine <engine>", "GPT-3 model to use")
.option("-t, --temperature <temperature>", "Response temperature")
.usage(`"<project-directory>" [options]`)
.action((options) => {
intro();
apiKeyPrompt().then((apiKey) => {
const prompt = async () => {
const response = await prompts({
type: "text",
name: "value",
message: `${chalk.blueBright("You: ")}`,
validate: () => {
return true;
},
});

switch (response.value) {
case "exit":
return process.exit(0);
case "clear":
return process.stdout.write("\x1Bc");
default:
generateResponse(apiKey, prompt, options, response);
return;
}
};

prompt();
});
});

commander.parse(process.argv);
121 changes: 0 additions & 121 deletions bin/terminalGPT.js

This file was deleted.

Loading

0 comments on commit e4e5893

Please sign in to comment.