Skip to content

Commit

Permalink
feat: include the keyv-file adapter for CLI and API users
Browse files Browse the repository at this point in the history
  • Loading branch information
waylaidwanderer committed Feb 2, 2023
1 parent 3170de2 commit 1589a43
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,4 @@ dist
settings.js
test.js
*.cast
cache.json
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ By itself, the model does not have any conversational support, so this library u
- Includes a CLI interface where you can chat with ChatGPT.
- Replicates chat threads from the official ChatGPT website (with conversation IDs and message IDs), with persistent conversations using [Keyv](https://www.npmjs.com/package/keyv).
- Conversations are stored in memory by default, but you can optionally [install a storage adapter](https://www.npmjs.com/package/keyv#usage) to persist conversations to a database.
- The `keyv-file` adapter is also included in this package, and can be used to store conversations in a JSON file if you're using the API server or CLI (see `settings.example.js`).
- Supports configurable prompt prefixes, and custom names for the user and ChatGPT.
- In essence, this allows you to turn ChatGPT into a different character.
- This is currently only configurable on a global level, but I plan to add support for per-conversation customization.
Expand Down Expand Up @@ -116,6 +117,9 @@ module.exports = {
cacheOptions: {},
// The port the server will run on (optional, defaults to 3000)
port: 3000,
// If set, ChatGPTClient will use `keyv-file` to store conversations to this JSON file instead of in memory.
// `cacheOptions.store` will override this if set
storageFilePath: './cache.json',
};
```

Expand Down
15 changes: 15 additions & 0 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import boxen from 'boxen';
import ora from 'ora';
import clipboard from 'clipboardy';
import inquirer from 'inquirer';
import { KeyvFile } from 'keyv-file';

const arg = process.argv.find((arg) => arg.startsWith('--settings'));
let path;
Expand All @@ -29,6 +30,20 @@ if (fs.existsSync(path)) {
process.exit(1);
}

if (settings.storageFilePath && !settings.cacheOptions.store) {
// make the directory and file if they don't exist
const dir = settings.storageFilePath.split('/').slice(0, -1).join('/');
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
if (!fs.existsSync(settings.storageFilePath)) {
fs.writeFileSync(settings.storageFilePath, '');
}

settings.cacheOptions.store = new KeyvFile({ filename: settings.storageFilePath });
// TODO: actually do something with this
}

const chatGptClient = new ChatGPTClient(settings.openaiApiKey, settings.chatGptClient, settings.cacheOptions);

console.log(boxen('ChatGPT CLI', { padding: 0.7, margin: 1, borderStyle: 'double', dimBorder: true }));
Expand Down
14 changes: 14 additions & 0 deletions bin/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fastify from 'fastify';
import fs from 'fs';
import { pathToFileURL } from 'url'
import ChatGPTClient from '../src/ChatGPTClient.js';
import { KeyvFile } from 'keyv-file';

const arg = process.argv.find((arg) => arg.startsWith('--settings'));
let path;
Expand All @@ -26,6 +27,19 @@ if (fs.existsSync(path)) {
process.exit(1);
}

if (settings.storageFilePath && !settings.cacheOptions.store) {
// make the directory and file if they don't exist
const dir = settings.storageFilePath.split('/').slice(0, -1).join('/');
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
if (!fs.existsSync(settings.storageFilePath)) {
fs.writeFileSync(settings.storageFilePath, '');
}

settings.cacheOptions.store = new KeyvFile({ filename: settings.storageFilePath });
}

const chatGptClient = new ChatGPTClient(settings.openaiApiKey, settings.chatGptClient, settings.cacheOptions);

const server = fastify();
Expand Down
47 changes: 47 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"gpt-3-encoder": "^1.1.4",
"inquirer": "^9.1.4",
"keyv": "^4.5.2",
"keyv-file": "^0.2.0",
"node-fetch": "^3.3.0",
"ora": "^6.1.2"
}
Expand Down
3 changes: 3 additions & 0 deletions settings.example.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ export default {
cacheOptions: {},
// The port the server will run on (optional, defaults to 3000)
port: 3000,
// If set, ChatGPTClient will use `keyv-file` to store conversations to this JSON file instead of in memory.
// `cacheOptions.store` will override this if set
storageFilePath: './cache.json',
}
2 changes: 1 addition & 1 deletion src/ChatGPTClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export default class ChatGPTClient {
const userLabel = this.options.userLabel || 'User';
const chatGptLabel = this.options.chatGptLabel || 'ChatGPT';

const promptSuffix = `${chatGptLabel}:\n`; // Prompt should end with 2 newlines, so we add one here.
const promptSuffix = `${chatGptLabel}:\n`; // Prompt ChatGPT to respond.

let currentTokenCount = this.getTokenCount(`${promptPrefix}${promptSuffix}`);
let promptBody = '';
Expand Down

0 comments on commit 1589a43

Please sign in to comment.