| ``` | ||
| #!/usr/bin/env node | ||
| require('dotenv').config() | ||
| const fs = require('fs') | ||
| const path = require('path') | ||
| const yargs = require('yargs/yargs') | ||
| const inquirer = require('inquirer') | ||
| const { v4: uuidv4 } = require('uuid') | ||
| const { hideBin } = require('yargs/helpers') | ||
| const { getOpenAI, Conversation } = require('../lib/index.js') | ||
| function getRoot() { | ||
| return '.codepal' // TODO: get the root from start of git project | ||
| } | ||
| function getRootPath(...args) { | ||
| return path.join(getRoot(), ...args) | ||
| } | ||
| async function main() { | ||
| const { interactive, session, template, file, topp, temperature } = yargs(hideBin(process.argv)) | ||
| .option('interactive', { | ||
| alias: 'i', | ||
| type: 'boolean', | ||
| description: 'Start in interactive mode' | ||
| }) | ||
| .options('session', { | ||
| alias: 's', | ||
| type: 'string', | ||
| description: 'Session id/file to resume' | ||
| }) | ||
| .options('template', { | ||
| alias: 't', | ||
| type: 'string', | ||
| description: 'Template name/file to use' | ||
| }) | ||
| .options('file', { | ||
| alias: 'f', | ||
| type: 'string', | ||
| description: 'Start from a file' | ||
| }) | ||
| .options('topp', { | ||
| alias: 'p', | ||
| type: 'number', | ||
| description: 'The topP for the OpenAI API', | ||
| default: 1 | ||
| }) | ||
| .options('temperature', { | ||
| alias: 'm', | ||
| type: 'number', | ||
| description: 'The temperature for the OpenAI API', | ||
| default: 0.7 | ||
| }) | ||
| .parse() | ||
| let backstory | ||
| if (template) { | ||
| for (const file of [template, getRootPath('templates', template), getRootPath('templates', template + '.md')]) { | ||
| try { | ||
| backstory = (await fs.promises.readFile(file)).toString() | ||
| break | ||
| } catch (e) {} | ||
| } | ||
| if (!backstory) { | ||
| console.error(`x template ${template} not found`) | ||
| process.exit(1) | ||
| } | ||
| } | ||
| if (file) { | ||
| let fileContents | ||
| try { | ||
| fileContents = (await fs.promises.readFile(file)).toString() | ||
| } catch (e) { | ||
| console.error(`x file ${file} not found`) | ||
| process.exit(1) | ||
| } | ||
| backstory = `${backstory ? backstory + '\n\n' : ''}\`\`\`\n${fileContents}\`\`\`` | ||
| } | ||
| if (!process.env.OPENAI_API_KEY) { | ||
| throw new Error('Environment variable OPENAI_API_KEY not found') | ||
| } | ||
| const conversation = new Conversation({ | ||
| openai: getOpenAI(process.env.OPENAI_API_KEY), | ||
| backstory: backstory | ||
| }) | ||
| await Promise.all([ | ||
| fs.promises.mkdir(getRootPath('sessions'), { recursive: true }), | ||
| fs.promises.mkdir(getRootPath('templates'), { recursive: true }) | ||
| ]) | ||
| let sessionPath | ||
| if (session) { | ||
| let sessionContents | ||
| for (const file of [session, getRootPath('sessions', session), getRootPath('sessions', session + '.md')]) { | ||
| try { | ||
| sessionPath = file | ||
| sessionContents = (await fs.promises.readFile(file)).toString() | ||
| break | ||
| } catch (e) {} | ||
| } | ||
| if (!sessionContents) { | ||
| console.error(`x session ${session} not found`) | ||
| process.exit(1) | ||
| } | ||
| await conversation.loadConversation(sessionContents) | ||
| } else { | ||
| sessionPath = path.join('.codepal', 'sessions', `${uuidv4()}.md`) | ||
| } | ||
| if (interactive) { | ||
| while (true) { | ||
| const question = await inquirer.prompt([ | ||
| { | ||
| type: 'input', | ||
| name: 'message', | ||
| message: 'Q', | ||
| } | ||
| ]); | ||
| if (question.message.toLowerCase() === 'exit') { | ||
| break; | ||
| } | ||
| process.stdout.write('\n') | ||
| for await (const token of conversation.interact(question.message)) { | ||
| process.stdout.write(token) | ||
| } | ||
| process.stdout.write('\n') | ||
| await fs.promises.writeFile(sessionPath, conversation.dumpConversation()) | ||
| } | ||
| } else { | ||
| const questionChunks = [] | ||
| for await (const chunk of process.stdin) { | ||
| questionChunks.push(chunk) | ||
| } | ||
| const question = questionChunks.join('') | ||
| for await (const token of conversation.interact(question)) { | ||
| process.stdout.write(token) | ||
| } | ||
| process.stdout.write('\n') | ||
| await fs.promises.writeFile(sessionPath, conversation.dumpConversation()) | ||
| } | ||
| } | ||
| main() | ||
| ``` | ||
| [User] | ||
| Can you describe what this code does? | ||
| [Assistent] | ||
| This code is the main entry point for the CodePal project. It allows you to interact with the OpenAI API in a number of ways. It can read data from a template or a file, or you can start an interactive session which lets you enter data from the command line. It then saves the session to a file and can be resumed later. | ||
| [User] | ||
| Handle error for the call to main. | ||
| [Assistent] | ||
| If an error occurs when the main function is called, the code will display an error message and exit with a status code of 1. For example, if a template or session file cannot be found, the code will print an 'x' followed by the name of the file that could not be found and then exit with a status code of 1. | ||
| [User] | ||
| Just add a catch statement. | ||
| [Assistent] | ||
| You can add a catch statement to the main function to handle errors. The following code snippet shows an example of how to do this: | ||
| ``` | ||
| main() | ||
| .catch(err => { | ||
| console.error(err.message) | ||
| process.exit(1) | ||
| }) | ||
| ``` | ||
| [User] | ||
| What other parametes am I missing? | ||
| [Assistent] | ||
| You can pass in the following additional parameters: | ||
| - interactive: Starts the program in interactive mode | ||
| - session: The id or file of the session to resume | ||
| - template: The name or file of the template to use | ||
| - file: The file to start the conversation from | ||
| You can also set environment variables, such as OPENAI_API_KEY, to configure the OpenAI API. | ||
| [User] | ||
| What other parameters this project will benefit from? | ||
| [Assistent] | ||
| The project could benefit from additional parameters to configure the behavior of the conversation, such as how many responses to generate, how long to wait before typing a response, or how to format the output. | ||
| The project could also benefit from a way to detect when the user is finished with the conversation and a way to automatically save the session. Additionally, it could benefit from a way to pass in an environment variable to specify the root of the project, so the project can run from any directory. | ||
| [User] | ||
| I already do that. What else? | ||
| [Assistent] | ||
| The project could also benefit from a way to detect when the user is finished with the conversation and a way to automatically save the session when the conversation ends. Additionally, it could benefit from a way to pass in an environment variable to specify the root of the project, so the project can run from any directory. | ||
| It could also benefit from a way to add custom commands to the interactive session, so the user can interact with the project in a more user friendly way. Finally, it could benefit from a way to integrate with other services, such as a database, or to be able to query external APIs. | ||
| [User] | ||
| Can you add options to handle topP and temperature. | ||
| [Assistent] | ||
| Yes, you can add options to handle topP and temperature. The OpenAI API allows for these values to be set when a conversation is initialized. The following code snippet shows an example of how to do this: | ||
| ``` | ||
| const conversation = new Conversation({ | ||
| openai: getOpenAI(process.env.OPENAI_API_KEY), | ||
| topP: 0.5, | ||
| temperature: 0.5, | ||
| backstory: backstory | ||
| }) | ||
| ``` | ||
| [User] | ||
| But also link them to yargs options. | ||
| [Assistent] | ||
| Yes, you can link topP and temperature to yargs options. The following code snippet shows an example of how to do this: | ||
| ``` | ||
| const { getOpenAI, Conversation } = require('../lib/index.js') | ||
| function getRoot() { | ||
| return '.codepal' // TODO: get the root from start of git project | ||
| } | ||
| function getRootPath(...args) { | ||
| return path.join(getRoot(), ...args) | ||
| } | ||
| async function main() { | ||
| const { interactive, session, template, file, topP, temperature } = yargs(hideBin(process.argv)) | ||
| .option('interactive', { | ||
| alias: 'i', | ||
| type: 'boolean', | ||
| description: 'Start in interactive mode' | ||
| }) | ||
| .options('session', { | ||
| alias: 's', | ||
| type: 'string', | ||
| description: 'Session id/file to resume' | ||
| }) | ||
| .options('template', { | ||
| alias: 't', | ||
| type: 'string', | ||
| description: 'Template name/file to use' | ||
| }) | ||
| .options('file', { | ||
| alias: 'f', | ||
| type: 'string', | ||
| description: 'Start from a file' | ||
| }) | ||
| .options('topP', { | ||
| alias: 'p', | ||
| type: 'number', | ||
| description: 'The topP for the OpenAI API' | ||
| }) | ||
| .options('temperature', { | ||
| alias: 'temperature', | ||
| type: 'number', | ||
| description: 'The temperature for the OpenAI API' | ||
| }) | ||
| .parse() | ||
| let backstory | ||
| if (template) { | ||
| for (const file of [template, getRootPath('templates', template), getRootPath('templates', template + '.md')]) { | ||
| try { | ||
| backstory = (await fs.promises.readFile(file)).toString() | ||
| break | ||
| } catch (e) {} | ||
| } | ||
| if (!backstory) { | ||
| console.error(`x template ${template} not found`) | ||
| process.exit(1) | ||
| } | ||
| } | ||
| if (file) { | ||
| let fileContents | ||
| try { | ||
| fileContents = (await fs.promises.readFile(file)).toString() | ||
| } catch (e) { | ||
| console.error(`x file ${file} not found`) | ||
| process.exit(1) | ||
| } | ||
| backstory = `${backstory ? backstory + '\n\n' : ''}\`\`\`\n${fileContents}\`\`\`` | ||
| } | ||
| if (!process.env.OPENAI_API_KEY) { | ||
| throw new Error('Environment variable OPENAI_API_KEY not found') | ||
| } | ||
| const conversation = new Conversation({ | ||
| openai: getOpenAI(process.env.OPENAI_API_KEY), | ||
| topP: topP, | ||
| temperature: temperature, | ||
| backstory: backstory | ||
| }) | ||
| await Promise.all([ | ||
| fs.promises.mkdir(getRootPath('sessions'), { recursive: true }), | ||
| fs.promises.mkdir(getRootPath('templates'), { recursive: true }) | ||
| ]) | ||
| let sessionPath | ||
| if (session) { | ||
| let sessionContents | ||
| for (const file of [session, getRootPath('sessions', session), getRootPath('sessions', session + '.md')]) { | ||
| try { | ||
| sessionPath = file | ||
| sessionContents = (await fs.promises.readFile(file)).toString() | ||
| break | ||
| } catch (e) {} | ||
| } | ||
| if (!sessionContents) { | ||
| console.error(`x session ${session} not found`) | ||
| process.exit(1) | ||
| } | ||
| await conversation.loadConversation(sessionContents) | ||
| } else { | ||
| sessionPath = path.join('.codepal', 'sessions', `${uuidv4()}.md`) | ||
| } | ||
| // ... | ||
| } | ||
| main() | ||
| ``` |
| ``` | ||
| # CodePal | ||
| CodePal is a command line tool with a chat interface that helps developers write code. It is built on top of GPT-3 and ChatGPT (which is a work in progress), and provides a convenient and intuitive way for developers to write code quickly and efficiently. | ||
| ## Features | ||
| - Chat-based interface that allows for natural, conversational code writing | ||
| - Built on top of GPT-3 and ChatGPT (soon), providing state-of-the-art natural language processing capabilities | ||
| - Easy to use and customize to your personal coding style | ||
| ## Installation | ||
| To install CodePal, simply run the following command: | ||
| ```sh | ||
| npm install codepal | ||
| ``` | ||
| To install it globally use: | ||
| ```sh | ||
| npm install -g codepal | ||
| ``` | ||
| ## Usage | ||
| Before using CodePal, you will need to set up an environment variable with your OpenAI credentials. This can be done by adding the following line to a `.env` file in your project directory: | ||
| ``` | ||
| OPENAI_API_KEY=YOUR_API_KEY_HERE | ||
| ``` | ||
| Once you've set up the environment variable, you can use CodePal by navigating to the directory where you want to write your code and running the following command: | ||
| ```sh | ||
| npx codepal | ||
| ``` | ||
| This will start the CodePal chat interface, where you can write your code using natural language. CodePal will save your chat history in a directory called `.codepal` in your current working folder. To continue a previous chat session, you can provide the path to the chat history file, like this: | ||
| ```sh | ||
| npx codepal .codepal/b1a7e548-da06-48be-9844-50f9b9c9436b.md | ||
| ``` | ||
| Alternatively, you can just provide the filename (without the path), like this: | ||
| ```sh | ||
| npx codepal b1a7e548-da06-48be-9844-50f9b9c9436b | ||
| ``` | ||
| In this case, CodePal will automatically look for the chat history file in the `.codepal` directory of your current working folder. | ||
| The command line tool will also be made aware of git in the coming weeks/days, allowing for even more convenient code writing. | ||
| ## Examples | ||
| Examples of using CodePal can be found in the `.codepal` directory of your project. These examples show different ways to use CodePal to write code, and can serve as a useful reference for getting started with the tool. | ||
| ## License | ||
| CodePal is licensed under the [MIT license](LICENSE). | ||
| ``` | ||
| [User] | ||
| I need to extend the readme file to mention that codepal can be executed directly via npx. | ||
| [Assistent] | ||
| Sure, I can help you with that. To execute CodePal directly via npx, you can use the following command: | ||
| ```sh | ||
| npx codepal | ||
| ``` | ||
| This will start the CodePal chat interface, where you can write your code using natural language. To continue a previous chat session, you can provide the path to the chat history file, like this: | ||
| ```sh | ||
| npx codepal .codepal/b1a7e548-da06-48be-9844-50f9b9c9436b.md | ||
| ``` | ||
| Alternatively, you can just provide the filename (without the path), like this: | ||
| ```sh | ||
| npx codepal b1a7e548-da06-48be-9844-50f9b9c9436b | ||
| ``` | ||
| In this case, CodePal will automatically look for the chat history file in the `.codepal` directory of your current working folder. | ||
| [User] | ||
| Show me what the README.md file looks like. | ||
| [Assistent] | ||
| Sure, here is the updated README.md file: | ||
| ``` | ||
| # CodePal | ||
| CodePal is a command line tool with a chat interface that helps developers write code. It is built on top of GPT-3 and ChatGPT (which is a work in progress), and provides a convenient and intuitive way for developers to write code quickly and efficiently. | ||
| ## Features | ||
| - Chat-based interface that allows for natural, conversational code writing | ||
| - Built on top of GPT-3 and ChatGPT (soon), providing state-of-the-art natural language processing capabilities | ||
| - Easy to use and customize to your personal coding style | ||
| ## Installation | ||
| To install CodePal, simply run the following command: | ||
| ```sh | ||
| npm install codepal | ||
| ``` | ||
| To install it globally use: | ||
| ```sh | ||
| npm install -g codepal | ||
| ``` | ||
| ## Usage | ||
| Before using CodePal, you will need to set up an environment variable with your OpenAI credentials. This can be done by adding the following line to a `.env` file in your project directory: | ||
| ``` | ||
| OPENAI_API_KEY=YOUR_API_KEY_HERE | ||
| ``` | ||
| Once you've set up the environment variable, you can use CodePal by navigating to the directory where you want to write your code and running the following command: | ||
| ```sh | ||
| npx codepal | ||
| ``` | ||
| This will start the CodePal chat interface, where you can write your code using natural language. CodePal will save your chat history in a directory called `.codepal` in your current working folder. To continue a previous chat session, you can provide the path to the chat history file, like this: | ||
| ```sh | ||
| npx codepal .codepal/b1a7e548-da06-48be-9844-50f9b9c9436b.md | ||
| ``` | ||
| Alternatively, you can just provide the filename (without the path), like this: | ||
| ```sh | ||
| npx codepal b1a7e548-da06-48be-9844-50f9b9c9436b | ||
| ``` | ||
| In this case, CodePal will automatically look for the chat history file in the `.codepal` directory of your current working folder. The command line tool can also be executed directly via npx. | ||
| The command line tool will also be made aware of git in the coming weeks/days, allowing for even more convenient code writing. | ||
| ## Examples | ||
| Examples of using CodePal can be found in the `.codepal` directory of your project. These examples show different ways to use CodePal to write code, and can serve as a useful reference for getting started with the tool. | ||
| ## License | ||
| CodePal is licensed under the [MIT license](LICENSE). | ||
| ``` | ||
| [User] | ||
| For interactive mode the user need to use the -i flag. And in order to resume a session the user needs to use the -s flag. There is also a flag to start with a pre-defined template. The flag is -t. Templates are effectively like pre-prompts that will be added at the beggining of the session. There is another flag `-f`, which is used to pre prompt with the contents of a file. Can you add these into the readme and describe what they do? | ||
| [Assistent] | ||
| Sure, I can add these flags to the README.md. The `-i` flag is used to start CodePal in interactive mode, which allows you to write code using natural language. The `-s` flag is used to resume a previous chat session, and the `-t` flag is used to start with a pre-defined template. The `-f` flag is used to pre prompt with the contents of a file. | ||
| [User] | ||
| Expand on those and add them to the usage section of the readme. | ||
| [Assistent] | ||
| Sure, here is the updated README.md file: | ||
| ``` | ||
| # CodePal | ||
| CodePal is a command line tool with a chat interface that helps developers write code. It is built on top of GPT-3 and ChatGPT (which is a work in progress), and provides a convenient and intuitive way for developers to write code quickly and efficiently. | ||
| ## Features | ||
| - Chat-based interface that allows for natural, conversational code writing | ||
| - Built on top of GPT-3 and ChatGPT (soon), providing state-of-the-art natural language processing capabilities | ||
| - Easy to use and customize to your personal coding style | ||
| ## Installation | ||
| To install CodePal, simply run the following command: | ||
| ```sh | ||
| npm install codepal | ||
| ``` | ||
| To install it globally use: | ||
| ```sh | ||
| npm install -g codepal | ||
| ``` | ||
| ## Usage | ||
| Before using CodePal, you will need to set up an environment variable with your OpenAI credentials. This can be done by adding the following line to a `.env` file in your project directory: | ||
| ``` | ||
| OPENAI_API_KEY=YOUR_API_KEY_HERE | ||
| ``` | ||
| Once you've set up the environment variable, you can use CodePal by navigating to the directory where you want to write your code and running the following command: | ||
| ```sh | ||
| npx codepal | ||
| ``` | ||
| This will start the CodePal chat interface, where you can write your code using natural language. CodePal will save your chat history in a directory called `.codepal` in your current working folder. To continue a previous chat session, you can provide the path to the chat history file, like this: | ||
| ```sh | ||
| npx codepal .codepal/b1a7e548-da06-48be-9844-50f9b9c9436b.md | ||
| ``` | ||
| Alternatively, you can just provide the filename (without the path), like this: | ||
| ```sh | ||
| npx codepal b1a7e548-da06-48be-9844-50f9b9c9436b | ||
| ``` | ||
| In this case, CodePal will automatically look for the chat history file in the `.codepal` directory of your current working folder. The command line tool can also be executed directly via npx. Additionally, there are several flags that can be used to customize the experience. The `-i` flag is used to start CodePal in interactive mode, the `-s` flag is used to resume a previous chat session, the `-t` flag is used to start with a pre-defined template, and the `-f` flag is used to pre prompt with the contents of a file. | ||
| The command line tool will also be made aware of git in the coming weeks/days, allowing for even more convenient code writing. | ||
| ## Examples | ||
| Examples of using CodePal can be found in the `.codepal` directory of your project. These examples show different ways to use CodePal to write code, and can serve as a useful reference for getting started with the tool. | ||
| ## License | ||
| CodePal is licensed under the [MIT license](LICENSE). | ||
| ``` | ||
| [User] | ||
| Can you put the different flags into a markdown table? | ||
| [Assistent] | ||
| Sure, here is the updated README.md file: | ||
| ``` | ||
| # CodePal | ||
| CodePal is a command line tool with a chat interface that helps developers write code. It is built on top of GPT-3 and ChatGPT (which is a work in progress), and provides a convenient and intuitive way for developers to write code quickly and efficiently. | ||
| ## Features | ||
| - Chat-based interface that allows for natural, conversational code writing | ||
| - Built on top of GPT-3 and ChatGPT (soon), providing state-of-the-art natural language processing capabilities | ||
| - Easy to use and customize to your personal coding style | ||
| ## Installation | ||
| To install CodePal, simply run the following command: | ||
| ```sh | ||
| npm install codepal | ||
| ``` | ||
| To install it globally use: | ||
| ```sh | ||
| npm install -g codepal | ||
| ``` | ||
| ## Usage | ||
| Before using CodePal, you will need to set up an environment variable with your OpenAI credentials. This can be done by adding the following line to a `.env` file in your project directory: | ||
| ``` | ||
| OPENAI_API_KEY=YOUR_API_KEY_HERE | ||
| ``` | ||
| Once you've set up the environment variable, you can use CodePal by navigating to the directory where you want to write your code and running the following command: | ||
| ```sh | ||
| npx codepal | ||
| ``` | ||
| This will start the CodePal chat interface, where you can write your code using natural language. CodePal will save your chat history in a directory called `.codepal` in your current working folder. To continue a previous chat session, you can provide the path to the chat history file, like this: | ||
| ```sh | ||
| npx codepal .codepal/b1a7e548-da06-48be-9844-50f9b9c9436b.md | ||
| ``` | ||
| Alternatively, you can just provide the filename (without the path), like this: | ||
| ```sh | ||
| npx codepal b1a7e548-da06-48be-9844-50f9b9c9436b | ||
| ``` | ||
| In this case, CodePal will automatically look for the chat history file in the `.codepal` directory of your current working folder. The command line tool can also be executed directly via npx. Additionally, there are several flags that can be used to customize the experience. | ||
| | Flag | Description | | ||
| | --- | --- | | ||
| | -i | Starts CodePal in interactive mode | | ||
| | -s | Resumes a previous chat session | | ||
| | -t | Starts with a pre-defined template | | ||
| | -f | Pre prompt with the contents of a file | | ||
| The command line tool will also be made aware of git in the coming weeks/days, allowing for even more convenient code writing. | ||
| ## Examples | ||
| Examples of using CodePal can be found in the `.codepal` directory of your project. These examples show different ways to use CodePal to write code, and can serve as a useful reference for getting started with the tool. | ||
| ## License | ||
| CodePal is licensed under the [MIT license](LICENSE). | ||
| ``` | ||
| [User] | ||
| In the example with `npx` please use -s to denote that this is a session to be resume. | ||
| [Assistent] | ||
| Sure, here is the updated README.md file: | ||
| ``` | ||
| # CodePal | ||
| CodePal is a command line tool with a chat interface that helps developers write code. It is built on top of GPT-3 and ChatGPT (which is a work in progress), and provides a convenient and intuitive way for developers to write code quickly and efficiently. | ||
| ## Features | ||
| - Chat-based interface that allows for natural, conversational code writing | ||
| - Built on top of GPT-3 and ChatGPT (soon), providing state-of-the-art natural language processing capabilities | ||
| - Easy to use and customize to your personal coding style | ||
| ## Installation | ||
| To install CodePal, simply run the following command: | ||
| ```sh | ||
| npm install codepal | ||
| ``` | ||
| To install it globally use: | ||
| ```sh | ||
| npm install -g codepal | ||
| ``` | ||
| ## Usage | ||
| Before using CodePal, you will need to set up an environment variable with your OpenAI credentials. This can be done by adding the following line to a `.env` file in your project directory: | ||
| ``` | ||
| OPENAI_API_KEY=YOUR_API_KEY_HERE | ||
| ``` | ||
| Once you've set up the environment variable, you can use CodePal by navigating to the directory where you want to write your code and running the following command: | ||
| ```sh | ||
| npx codepal | ||
| ``` | ||
| This will start the CodePal chat interface, where you can write your code using natural language. CodePal will save your chat history in a directory called `.codepal` in your current working folder. To continue a previous chat session, you can provide the path to the chat history file, like this: | ||
| ```sh | ||
| npx codepal -s .codepal/b1a7e548-da06-48be-9844-50f9b9c9436b.md | ||
| ``` | ||
| Alternatively, you can just provide the filename (without the path), like this: | ||
| ```sh | ||
| npx codepal -s b1a7e548-da06-48be-9844-50f9b9c9436b | ||
| ``` | ||
| In this case, CodePal will automatically look for the chat history file in the `.codepal` directory of your current working folder. The command line tool can also be executed directly via npx. Additionally, there are several flags that can be used to customize the experience. | ||
| | Flag | Description | | ||
| | --- | --- | | ||
| | -i | Starts CodePal in interactive mode | | ||
| | -s | Resumes a previous chat session | | ||
| | -t | Starts with a pre-defined template | | ||
| | -f | Pre prompt with the contents of a file | | ||
| The command line tool will also be made aware of git in the coming weeks/days, allowing for even more convenient code writing. | ||
| ## Examples | ||
| Examples of using CodePal can be found in the `.codepal` directory of your project. These examples show different ways to use CodePal to write code, and can serve as a useful reference for getting started with the tool. | ||
| ## License | ||
| CodePal is licensed under the [MIT license](LICENSE). | ||
| ``` | ||
| [User] | ||
| Breakdown this text "In this case, CodePal will automatically look for the chat history file in the `.codepal` directory of your current working folder. The command line tool can also be executed directly via npx. Additionally, there are several flags that can be used to customize the experience."so that it reads a s a little bit better | ||
| [Assistent] | ||
| Sure, here is the updated text: | ||
| In this case, CodePal will automatically search for the chat history file in the `.codepal` directory of your current working folder. The command line tool can also be executed directly with npx. Additionally, there are several flags available that can be used to customize your experience. | ||
| [User] | ||
| Split it up to new lines and add more clarification please. | ||
| [Assistent] | ||
| Sure, here is the updated text: | ||
| In this case, CodePal will automatically search for the chat history file in the `.codepal` directory of your current working folder. | ||
| The command line tool can also be executed directly with npx. | ||
| Additionally, there are several flags available that can be used to customize your experience when using CodePal. | ||
| [User] | ||
| Describe what NPX is when you are referring to it. | ||
| [Assistent] | ||
| Sure, here is the updated text: | ||
| In this case, CodePal will automatically search for the chat history file in the `.codepal` directory of your current working folder. | ||
| The command line tool can also be executed directly with npx, which is a package runner for npm packages. | ||
| Additionally, there are several flags available that can be used to customize your experience when using CodePal. | ||
| [User] | ||
| Show me the contents of the readme file. | ||
| [Assistent] | ||
| Sure, here is the content of the README.md file: | ||
| ``` | ||
| # CodePal | ||
| CodePal is a command line tool with a chat interface that helps developers write code. It is built on top of GPT-3 and ChatGPT (which is a work in progress), and provides a convenient and intuitive way for developers to write code quickly and efficiently. | ||
| ## Features | ||
| - Chat-based interface that allows for natural, conversational code writing | ||
| - Built on top of GPT-3 and ChatGPT (soon), providing state-of-the-art natural language processing capabilities | ||
| - Easy to use and customize to your personal coding style | ||
| ## Installation | ||
| To install CodePal, simply run the following command: | ||
| ```sh | ||
| npm install codepal | ||
| ``` | ||
| To install it globally use: | ||
| ```sh | ||
| npm install -g codepal | ||
| ``` | ||
| ## Usage | ||
| Before using CodePal, you will need to set up an environment variable with your OpenAI credentials. This can be done by adding the following line to a `.env` file in your project directory: | ||
| ``` | ||
| OPENAI_API_KEY=YOUR_API_KEY_HERE | ||
| ``` | ||
| Once you've set up the environment variable, you can use CodePal by navigating to the directory where you want to write your code and running the following command: | ||
| ```sh | ||
| npx codepal | ||
| ``` | ||
| This will start the CodePal chat interface, where you can write your code using natural language. CodePal will save your chat history in a directory called `.codepal` in your current working folder. To continue a previous chat session, you can provide the path to the chat history file, like this: | ||
| ```sh | ||
| npx codepal -s .codepal/b1a7e548-da06-48be-9844-50f9b9c9436b.md | ||
| ``` | ||
| Alternatively, you can just provide the filename (without the path), like this: | ||
| ```sh | ||
| npx codepal -s b1a7e548-da06-48be-9844-50f9b9c9436b | ||
| ``` | ||
| In this case, CodePal will automatically search for the chat history file in the `.codepal` directory of your current working folder. The command line tool can also be executed directly with npx, which is a package runner for npm packages. Additionally, there are several flags available that can be used to customize your experience when using CodePal. | ||
| ## Examples | ||
| Examples of using CodePal can be found in the `.codepal` directory of your project. These examples show different ways to use CodePal to write code, and can serve as a useful reference for getting started with the tool. | ||
| ## License | ||
| CodePal is licensed under the [MIT license](LICENSE). | ||
| ``` |
| [User] | ||
| Show me how to calculate Fibonacci in JavaScript. | ||
| [Assistent] | ||
| Here is one way of calculating Fibonacci in JavaScript: | ||
| // Create a function to calculate Fibonacci | ||
| function fibo(n) { | ||
| // Declare an array | ||
| let arr = [0, 1]; | ||
| // Add the previous two numbers in the array | ||
| // and push to new array | ||
| for (let i = 2; i < n + 1; i++){ | ||
| arr.push(arr[i - 2] + arr[i -1]) | ||
| } | ||
| // Return the last number of the array | ||
| return arr[n] | ||
| } | ||
| console.log(fibo(7)); // 13, answer is 13 | ||
| [User] | ||
| Can you convert this in Rust? | ||
| [Assistent] | ||
| Sure, here is a way of calculating Fibonacci in Rust: | ||
| // Create a function to calculate Fibonacci | ||
| fn fibonacci(n: u32) -> u32 { | ||
| // Use an if statement | ||
| // to return the first | ||
| // two numbers of series | ||
| if n == 0 { | ||
| 0 | ||
| } else if n == 1 { | ||
| 1 | ||
| } else { | ||
| fibonacci(n - 1) + fibonacci(n - 2) | ||
| } | ||
| } | ||
| // Print the last number of the array | ||
| println!("{}", fibonacci(7));// 13, test passed |
+132
-25
@@ -7,23 +7,112 @@ #!/usr/bin/env node | ||
| const path = require('path') | ||
| const yargs = require('yargs/yargs') | ||
| const inquirer = require('inquirer') | ||
| const { v4: uuidv4 } = require('uuid') | ||
| const { hideBin } = require('yargs/helpers') | ||
| const { getOpenAI, Conversation } = require('../lib/index.js') | ||
| function getRoot() { | ||
| return '.codepal' // TODO: get the root from start of git project | ||
| } | ||
| function getRootPath(...args) { | ||
| return path.join(getRoot(), ...args) | ||
| } | ||
| async function main() { | ||
| let conversationPath | ||
| const { interactive, session, template, file, topp, temperature } = yargs(hideBin(process.argv)) | ||
| .option('interactive', { | ||
| alias: 'i', | ||
| type: 'boolean', | ||
| description: 'Start in interactive mode' | ||
| }) | ||
| .options('session', { | ||
| alias: 's', | ||
| type: 'string', | ||
| description: 'Session id/file to resume' | ||
| }) | ||
| .options('template', { | ||
| alias: 't', | ||
| type: 'string', | ||
| description: 'Template name/file to use' | ||
| }) | ||
| .options('file', { | ||
| alias: 'f', | ||
| type: 'string', | ||
| description: 'Start from a file' | ||
| }) | ||
| .options('topp', { | ||
| alias: 'p', | ||
| type: 'number', | ||
| description: 'The topP for the OpenAI API', | ||
| default: 1 | ||
| }) | ||
| .options('temperature', { | ||
| alias: 'm', | ||
| type: 'number', | ||
| description: 'The temperature for the OpenAI API', | ||
| default: 0.7 | ||
| }) | ||
| .parse() | ||
| await fs.promises.mkdir('.codepal', { recursive: true }) | ||
| let backstory | ||
| if (template) { | ||
| for (const file of [template, getRootPath('templates', template), getRootPath('templates', template + '.md')]) { | ||
| try { | ||
| backstory = (await fs.promises.readFile(file)).toString() | ||
| break | ||
| } catch (e) {} | ||
| } | ||
| if (!backstory) { | ||
| console.error(`x template ${template} not found`) | ||
| process.exit(1) | ||
| } | ||
| } | ||
| if (file) { | ||
| let fileContents | ||
| try { | ||
| fileContents = (await fs.promises.readFile(file)).toString() | ||
| } catch (e) { | ||
| console.error(`x file ${file} not found`) | ||
| process.exit(1) | ||
| } | ||
| backstory = `${backstory ? backstory + '\n\n' : ''}file: ${file}\n\`\`\`\n${fileContents}\`\`\`` | ||
| } | ||
| if (!process.env.OPENAI_API_KEY) { | ||
| throw new Error('Environment variable OPENAI_API_KEY not found') | ||
| } | ||
| const conversation = new Conversation({ | ||
| openai: getOpenAI(process.env.OPENAI_API_KEY) | ||
| openai: getOpenAI(process.env.OPENAI_API_KEY), | ||
| backstory: backstory, | ||
| topP: topp, | ||
| temperature: temperature | ||
| }) | ||
| if (process.argv[2]) { | ||
| let conversationContents | ||
| await Promise.all([ | ||
| fs.promises.mkdir(getRootPath('sessions'), { recursive: true }), | ||
| fs.promises.mkdir(getRootPath('templates'), { recursive: true }) | ||
| ]) | ||
| for (const file of [process.argv[2], path.join('.codepal', process.argv[2]), path.join('.codepal', process.argv[2] + '.md')]) { | ||
| let sessionPath | ||
| if (session) { | ||
| let sessionContents | ||
| for (const file of [session, getRootPath('sessions', session), getRootPath('sessions', session + '.md')]) { | ||
| try { | ||
| conversationPath = file | ||
| conversationContents = await fs.promises.readFile(file) | ||
| sessionPath = file | ||
| sessionContents = (await fs.promises.readFile(file)).toString() | ||
@@ -34,4 +123,4 @@ break | ||
| if (!conversationContents) { | ||
| console.error(`[x] session ${process.argv[2]} not found`) | ||
| if (!sessionContents) { | ||
| console.error(`x session ${session} not found`) | ||
@@ -41,24 +130,42 @@ process.exit(1) | ||
| await conversation.loadConversation(conversationContents.toString()) | ||
| await conversation.loadConversation(sessionContents) | ||
| } else { | ||
| conversationPath = path.join('.codepal', `${uuidv4()}.md`) | ||
| sessionPath = path.join('.codepal', 'sessions', `${uuidv4()}.md`) | ||
| } | ||
| while (true) { | ||
| const question = await inquirer.prompt([ | ||
| { | ||
| type: 'input', | ||
| name: 'message', | ||
| message: 'Q', | ||
| if (interactive) { | ||
| while (true) { | ||
| const question = await inquirer.prompt([ | ||
| { | ||
| type: 'input', | ||
| name: 'message', | ||
| message: 'Q', | ||
| } | ||
| ]); | ||
| if (question.message.toLowerCase() === 'exit') { | ||
| break; | ||
| } | ||
| ]); | ||
| if (question.message.toLowerCase() === 'exit') { | ||
| break; | ||
| process.stdout.write('\n') | ||
| for await (const token of conversation.interact(question.message)) { | ||
| process.stdout.write(token) | ||
| } | ||
| process.stdout.write('\n') | ||
| await fs.promises.writeFile(sessionPath, conversation.dumpConversation()) | ||
| } | ||
| } else { | ||
| const questionChunks = [] | ||
| process.stdout.write('\n') | ||
| for await (const chunk of process.stdin) { | ||
| questionChunks.push(chunk) | ||
| } | ||
| for await (const token of conversation.interact(question.message)) { | ||
| process.stdout.write(token) | ||
| const question = questionChunks.join('') | ||
| for await (const token of conversation.interact(question)) { | ||
| process.stdout.write(token) | ||
| } | ||
@@ -68,3 +175,3 @@ | ||
| await fs.promises.writeFile(conversationPath, conversation.dumpConversation()) | ||
| await fs.promises.writeFile(sessionPath, conversation.dumpConversation()) | ||
| } | ||
@@ -71,0 +178,0 @@ } |
+60
-11
@@ -19,5 +19,21 @@ const split = require('split2') | ||
| maxTokens = 4097, | ||
| halfTokens = maxTokens / 2, | ||
| temperature = 0.9, | ||
| topP = 1, | ||
| openai = getOpenAI() | ||
| } = options | ||
| this.backstory = backstory | ||
| this.maxTokens = maxTokens | ||
| this.halfTokens = halfTokens | ||
| this.temperature = temperature | ||
| this.topP = topP | ||
| this.openai = openai | ||
@@ -51,10 +67,28 @@ | ||
| estimateTokens(input) { | ||
| return this.tokenizer.encode(input).bpe.length | ||
| } | ||
| getPrompt(input) { | ||
| this.conversation.push(`[User]\n\n${input.trim()}\n\n[Assistent]`) // NOTE: vulnerable to prompt injection | ||
| return this.dumpConversation(this.conversation) | ||
| let totalTokensUsed = 0 | ||
| const conversation = [] | ||
| for (let i = this.conversation.length - 1; i >= 0; i--) { | ||
| totalTokensUsed += this.estimateTokens(this.conversation[i]) | ||
| if (totalTokensUsed > this.halfTokens) { | ||
| break | ||
| } | ||
| conversation.push(this.conversation[i]) | ||
| } | ||
| return this.dumpConversation(conversation.reverse()) | ||
| } | ||
| getMaxTokens(input) { | ||
| return Math.max(256, 4097 - this.tokenizer.encode(input).bpe.length) | ||
| return Math.max(256, this.maxTokens - this.estimateTokens(input)) | ||
| } | ||
@@ -66,3 +100,3 @@ | ||
| if (process.env.DEBUG) { | ||
| console.debug(`[*] using prompt ${JSON.stringify(prompt)}`) | ||
| console.debug(`* using prompt ${JSON.stringify(prompt)}`) | ||
| } | ||
@@ -73,12 +107,27 @@ | ||
| if (process.env.DEBUG) { | ||
| console.debug(`[*] using maxTokens ${JSON.stringify(maxTokens)}`) | ||
| console.debug(`* using maxTokens ${JSON.stringify(maxTokens)}`) | ||
| } | ||
| const response = await this.openai.createCompletion({ | ||
| model: "text-davinci-003", | ||
| prompt: prompt, | ||
| max_tokens: maxTokens, | ||
| stream: true | ||
| }, { responseType: 'stream' }) | ||
| let response | ||
| try { | ||
| response = await this.openai.createCompletion({ | ||
| model: "text-davinci-003", | ||
| prompt: prompt, | ||
| max_tokens: maxTokens, | ||
| temperature: this.temperature, | ||
| top_p: this.topP, | ||
| stop: '\n[User]', | ||
| stream: true | ||
| }, { responseType: 'stream' }) | ||
| } catch (e) { | ||
| if (process.env.DEBUG) { | ||
| console.error(e) | ||
| } | ||
| const { message } = e.toJSON() | ||
| throw new Error(message) | ||
| } | ||
| const tokens = new PassThrough({ objectMode: true }) | ||
@@ -116,3 +165,3 @@ | ||
| if (process.env.DEBUG) { | ||
| console.log(`[*] tokens consumed ${this.getMaxTokens(this.dumpConversation(this.conversation))}`) | ||
| console.log(`\n* tokens consumed ${this.getMaxTokens(this.dumpConversation(this.conversation))}`) | ||
| } | ||
@@ -119,0 +168,0 @@ } |
+3
-2
| { | ||
| "name": "codepal", | ||
| "version": "0.1.0", | ||
| "version": "0.2.0", | ||
| "description": "", | ||
@@ -30,4 +30,5 @@ "main": "lib/index.js", | ||
| "through2": "^4.0.2", | ||
| "uuid": "^9.0.0" | ||
| "uuid": "^9.0.0", | ||
| "yargs": "^17.6.2" | ||
| } | ||
| } |
+24
-5
@@ -19,2 +19,8 @@ # CodePal | ||
| To install it globally use: | ||
| ```sh | ||
| npm install -g codepal | ||
| ``` | ||
| ## Usage | ||
@@ -31,3 +37,3 @@ | ||
| ```sh | ||
| codepal | ||
| npx codepal | ||
| ``` | ||
@@ -38,3 +44,3 @@ | ||
| ```sh | ||
| codepal .codepal/b1a7e548-da06-48be-9844-50f9b9c9436b.md | ||
| npx codepal -s .codepal/b1a7e548-da06-48be-9844-50f9b9c9436b.md | ||
| ``` | ||
@@ -45,11 +51,24 @@ | ||
| ```sh | ||
| codepal b1a7e548-da06-48be-9844-50f9b9c9436b | ||
| npx codepal -s b1a7e548-da06-48be-9844-50f9b9c9436b | ||
| ``` | ||
| In this case, CodePal will automatically look for the chat history file in the `.codepal` directory of your current working folder. | ||
| In this case, CodePal will automatically search for the chat history file in the `.codepal` directory of your current working folder. | ||
| The command line tool will also be made aware of git in the coming weeks/days, allowing for even more convenient code writing. | ||
| The command line tool can also be executed directly with npx, which is a package runner for npm packages. | ||
| Additionally, there are several flags available that can be used to customize your experience when using CodePal. | ||
| | Flag | Description | | ||
| | --- | --- | | ||
| | -i | Starts CodePal in interactive mode | | ||
| | -s | Resumes a previous chat session | | ||
| | -t | Starts with a pre-defined template | | ||
| | -f | Pre prompt with the contents of a file | | ||
| ## Examples | ||
| Examples of using CodePal can be found in the `.codepal` directory of your project. These examples show different ways to use CodePal to write code, and can serve as a useful reference for getting started with the tool. | ||
| ## License | ||
| CodePal is licensed under the [MIT license](LICENSE). |
| [User] | ||
| Show me how to calculate Fibonacci in JavaScript. | ||
| [Assistent] | ||
| Here is one way of calculating Fibonacci in JavaScript: | ||
| // Create a function to calculate Fibonacci | ||
| function fibo(n) { | ||
| // Declare an array | ||
| let arr = [0, 1]; | ||
| // Add the previous two numbers in the array | ||
| // and push to new array | ||
| for (let i = 2; i < n + 1; i++){ | ||
| arr.push(arr[i - 2] + arr[i -1]) | ||
| } | ||
| // Return the last number of the array | ||
| return arr[n] | ||
| } | ||
| console.log(fibo(7)); // 13, answer is 13 | ||
| [User] | ||
| Can you convert this in Rust? | ||
| [Assistent] | ||
| Sure, here is a way of calculating Fibonacci in Rust: | ||
| // Create a function to calculate Fibonacci | ||
| fn fibonacci(n: u32) -> u32 { | ||
| // Use an if statement | ||
| // to return the first | ||
| // two numbers of series | ||
| if n == 0 { | ||
| 0 | ||
| } else if n == 1 { | ||
| 1 | ||
| } else { | ||
| fibonacci(n - 1) + fibonacci(n - 2) | ||
| } | ||
| } | ||
| // Print the last number of the array | ||
| println!("{}", fibonacci(7));// 13, test passed |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
41110
393.81%7
40%262
84.51%71
36.54%9
12.5%7
40%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added