Skip to content

Commit

Permalink
Chore: Update eslint config and fix linting errors
Browse files Browse the repository at this point in the history
Refactor: Rework how the root directory is resolved
  • Loading branch information
gmickel committed May 16, 2023
1 parent c93c9fb commit 2d10993
Show file tree
Hide file tree
Showing 25 changed files with 311 additions and 222 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.eslintrc.cjs
src/agentTest.ts
17 changes: 9 additions & 8 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
'plugin:@typescript-eslint/recommended'
],
parserOptions: {
project: './tsconfig.json'
project: './tsconfig.json',
},
settings: {
'import/parsers': {
Expand All @@ -18,14 +18,15 @@ module.exports = {
"alwaysTryTypes": true, // always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
project: './tsconfig.json'
}
parserOptions: {
project: './tsconfig.json',
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: ['@typescript-eslint', 'import']
}
},
parserOptions: {
project: './tsconfig.json',
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: ['@typescript-eslint', 'import'],
rules: {
'import/no-unresolved': 'error'
}
Expand Down
2 changes: 1 addition & 1 deletion src/chatLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ const logChat = async (logDirectory: string, question: string, answer: string):
}
};

export { logChat };
export default logChat;
23 changes: 12 additions & 11 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ function createCommandHandler(): CommandHandler {
return commands;
}

async function execute(commandName: string, args: string[], output: NodeJS.WriteStream) {
const command = commands.find((cmd) => cmd.name === commandName || cmd.aliases.includes(commandName));
if (command) {
await command.execute(args, output, commandHandler);
} else {
output.write(chalk.red('Unknown command. Type /help to see the list of available commands.\n'));
}
}

const commandHandler: CommandHandler = { getCommands, execute };
const commandHandler: CommandHandler = {
getCommands,
async execute(commandName: string, args: string[], output: NodeJS.WriteStream) {
const command = commands.find((cmd) => cmd.name === commandName || cmd.aliases.includes(commandName));
if (command) {
await command.execute(args, output, commandHandler);
} else {
output.write(chalk.red('Unknown command. Type /help to see the list of available commands.\n'));
}
},
};
return commandHandler;
}

export { createCommandHandler };
export default createCommandHandler;
4 changes: 2 additions & 2 deletions src/commands/addDocumentCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from 'chalk';
import { createCommand } from './command.js';
import createCommand from './command.js';
import { addDocument } from '../lib/contextManager.js';

const addDocumentCommand = createCommand(
Expand All @@ -8,7 +8,7 @@ const addDocumentCommand = createCommand(
`Adds new documents from your configured docs directory to the context vector store.\n
Usage: /add-docs example.txt example.md\n
Supports the following file types: .txt, .md, .pdf, .docx, .csv, .epub`,
async (args, output) => {
async (args: string[], output: NodeJS.WriteStream) => {
if (!args) {
output.write(chalk.red('Invalid number of arguments. Usage: /add-docs example.txt example.md\n'));
return;
Expand Down
6 changes: 3 additions & 3 deletions src/commands/addURLCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from 'chalk';
import { createCommand } from './command.js';
import createCommand from './command.js';
import { addURL } from '../lib/contextManager.js';

const addURLCommand = createCommand(
Expand All @@ -21,8 +21,8 @@ const addURLCommand = createCommand(
}
const url = args[0];
const selector = args[1];
const maxLinks = parseInt(args[2]) || 20;
const minChars = parseInt(args[3]) || 200;
const maxLinks = parseInt(args[2], 10) || 20;
const minChars = parseInt(args[3], 10) || 200;
await addURL(url, selector, maxLinks, minChars);
}
);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/addYouTubeCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from 'chalk';
import { createCommand } from './command.js';
import createCommand from './command.js';
import { addYouTube } from '../lib/contextManager.js';

const addYouTubeCommand = createCommand(
Expand Down
2 changes: 1 addition & 1 deletion src/commands/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ function createCommand(
): Command {
return { name, aliases, description, execute };
}
export { createCommand };
export default createCommand;
13 changes: 6 additions & 7 deletions src/commands/helpCommand.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import chalk from 'chalk';
import { createCommand } from './command.js';
import createCommand from './command.js';

const helpCommand = createCommand(
'help',
['h', '?'],
'Show the list of available commands',
(_args, output, commandHandler) => {
return new Promise<void>((resolve) => {
(_args, output, commandHandler) =>
new Promise<void>((resolve) => {
output.write(chalk.blue('Usage:\n'));
output.write('Ask memorybot to write some marketing materials and press enter.\n');
output.write(chalk.blue('\nAvailable commands:\n'));
for (const command of commandHandler.getCommands()) {
commandHandler.getCommands().forEach((command) => {
const aliases = command.aliases.length > 0 ? ` (/${command.aliases.join(', /')})` : '';
output.write(chalk.yellow(`/${command.name}${aliases}`));
output.write(` - ${command.description}`);
output.write('\n');
}
});
resolve();
});
}
})
);

export default helpCommand;
2 changes: 1 addition & 1 deletion src/commands/quitCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from 'chalk';
import { createCommand } from './command.js';
import createCommand from './command.js';

const exitCommand = createCommand('quit', ['q'], 'Terminates the script', (_args, output) => {
output.write(chalk.yellow('\nThanks for talking, bye!\n'));
Expand Down
2 changes: 1 addition & 1 deletion src/commands/resetChatCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from 'chalk';
import { createCommand } from './command.js';
import createCommand from './command.js';
import { resetBufferWindowMemory, resetMemoryVectorStore, setMemoryVectorStore } from '../lib/memoryManager.js';

const resetChatCommand = createCommand(
Expand Down
4 changes: 2 additions & 2 deletions src/commands/setContextConfigCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from 'chalk';
import { createCommand } from './command.js';
import createCommand from './command.js';
import { setNumContextDocumentsToRetrieve, getConfig } from '../config/index.js';

const setContextConfigCommand = createCommand(
Expand All @@ -13,7 +13,7 @@ const setContextConfigCommand = createCommand(
output.write(chalk.red('Invalid number of arguments. Usage: /context-config `number of documents`\n'));
return;
}
const numContextDocumentsToRetrieve = parseInt(args[0]);
const numContextDocumentsToRetrieve = parseInt(args[0], 10);
setNumContextDocumentsToRetrieve(numContextDocumentsToRetrieve);
const config = getConfig();
output.write(chalk.blue(`Number of context documents to retrieve set to ${config.numContextDocumentsToRetrieve}`));
Expand Down
4 changes: 2 additions & 2 deletions src/commands/setMemoryConfigCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from 'chalk';
import { createCommand } from './command.js';
import createCommand from './command.js';
import { setNumMemoryDocumentsToRetrieve, getConfig } from '../config/index.js';

const setMemoryConfigCommand = createCommand(
Expand All @@ -13,7 +13,7 @@ const setMemoryConfigCommand = createCommand(
output.write(chalk.red('Invalid number of arguments. Usage: /memory-config `number of documents`\n'));
return;
}
const numMemoryDocumentsToRetrieve = parseInt(args[0]);
const numMemoryDocumentsToRetrieve = parseInt(args[0], 10);
setNumMemoryDocumentsToRetrieve(numMemoryDocumentsToRetrieve);
const config = getConfig();
output.write(chalk.blue(`Number of memory documents to retrieve set to ${config.numMemoryDocumentsToRetrieve}`));
Expand Down
2 changes: 1 addition & 1 deletion src/commands/toggleWindowBufferMemory.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from 'chalk';
import { createCommand } from './command.js';
import createCommand from './command.js';
import { setUseWindowMemory, getConfig } from '../config/index.js';

const toggleWindowBufferMemory = createCommand(
Expand Down
8 changes: 8 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import type { Options } from 'ora';
import type { Writable } from 'stream';
import { fileURLToPath } from 'url';
import path from 'path';

export function getProjectRoot() {
const currentModulePath = fileURLToPath(import.meta.url);
const projectRoot = path.resolve(path.dirname(currentModulePath), '..', '..');
return projectRoot;
}

export function getDefaultOraOptions(output: Writable): Options {
return {
Expand Down
38 changes: 23 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
/* eslint-disable no-await-in-loop */
import dotenv from 'dotenv';
import { OpenAIChat } from 'langchain/llms/openai';
// eslint-disable-next-line import/no-unresolved
import * as readline from 'node:readline/promises';
import path from 'path';
import fs from 'fs';
/* This line of code is importing the `stdin` and `stdout` streams from the `process` module in
Node.js. These streams are used for reading input from the user and writing output to the console,
respectively. */
import { stdin as input, stdout as output } from 'node:process';
import { CallbackManager } from 'langchain/callbacks';
import { ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate } from 'langchain/prompts';
import { LLMChain } from 'langchain/chains';
import { oneLine } from 'common-tags';
import chalk from 'chalk';
import { logChat } from './chatLogger.js';
import { createCommandHandler } from './commands.js';
import logChat from './chatLogger.js';
import createCommandHandler from './commands.js';
import { getMemoryVectorStore, addDocumentsToMemoryVectorStore, getBufferWindowMemory } from './lib/memoryManager.js';
import { getContextVectorStore } from './lib/contextManager.js';
import { getRelevantContext } from './lib/vectorStoreUtils.js';
import { sanitizeInput } from './utils/string.js';
import { getConfig } from './config/index.js';
import sanitizeInput from './utils/sanitizeInput.js';
import { getConfig, getProjectRoot } from './config/index.js';

const projectRootDir = getProjectRoot();

dotenv.config();

const __dirname = new URL('..', import.meta.url).pathname;
const chatLogDirectory = path.join(__dirname, 'chat_logs');
const systemPromptTemplate = fs.readFileSync(path.join(__dirname, 'src/prompt.txt'), 'utf8');
const chatLogDirectory = path.join(projectRootDir, 'chat_logs');
const systemPromptTemplate = fs.readFileSync(path.join(projectRootDir, 'src/prompt.txt'), 'utf8');
const rl = readline.createInterface({ input, output });
const commandHandler: CommandHandler = createCommandHandler();
const contextVectorStore = await getContextVectorStore();
Expand All @@ -46,24 +52,25 @@ const chatPrompt = ChatPromptTemplate.fromPromptMessages([
HumanMessagePromptTemplate.fromTemplate('QUESTION: """{input}"""'),
]);

let windowMemory = getBufferWindowMemory();
const windowMemory = getBufferWindowMemory();

const chain = new LLMChain({
prompt: chatPrompt,
memory: windowMemory,
llm,
});

// eslint-disable-next-line no-constant-condition
while (true) {
output.write(chalk.green('\nStart chatting or type /help for a list of commands\n'));
const input = await rl.question('> ');
const userInput = await rl.question('> ');
let response;
if (input.startsWith('/')) {
const [command, ...args] = input.slice(1).split(' ');
if (userInput.startsWith('/')) {
const [command, ...args] = userInput.slice(1).split(' ');
await commandHandler.execute(command, args, output);
} else {
let memoryVectorStore = await getMemoryVectorStore();
const question = sanitizeInput(input);
const memoryVectorStore = await getMemoryVectorStore();
const question = sanitizeInput(userInput);
const config = getConfig();
const context = await getRelevantContext(contextVectorStore, question, config.numContextDocumentsToRetrieve);
const history = await getRelevantContext(memoryVectorStore, question, config.numMemoryDocumentsToRetrieve);
Expand All @@ -83,10 +90,11 @@ while (true) {
}
} catch (error) {
if (error instanceof Error && error.message.includes('Cancel:')) {
// TODO: Handle cancel
} else if (error instanceof Error) {
console.error(chalk.red(error.message));
output.write(chalk.red(error.message));
} else {
console.error(chalk.red(error));
output.write(chalk.red(error));
}
}
}
Expand Down
Loading

0 comments on commit 2d10993

Please sign in to comment.