Skip to content

Commit

Permalink
chore: apply linters
Browse files Browse the repository at this point in the history
  • Loading branch information
gharbat committed Jun 24, 2023
1 parent b17815e commit c2f99f1
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 149 deletions.
4 changes: 2 additions & 2 deletions llm-server/config/pinecone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
*/

if (!process.env.PINECONE_INDEX_NAME) {
throw new Error('Missing Pinecone index name in .env file');
throw new Error('Missing Pinecone index name in .env file');
}

const PINECONE_INDEX_NAME = process.env.PINECONE_INDEX_NAME ?? '';

const PINECONE_NAME_SPACE = 'bot-test'; //namespace is optional for your vectors

export { PINECONE_INDEX_NAME, PINECONE_NAME_SPACE };
export {PINECONE_INDEX_NAME, PINECONE_NAME_SPACE};
18 changes: 4 additions & 14 deletions llm-server/data-sources/codebaseHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,18 @@ import {GithubRepoLoader} from "langchain/document_loaders/web/github";
export default async function codebaseHandler(req: NextApiRequest, res: NextApiResponse) {
try {
const {repo, namespace} = req.body;

const loader = new GithubRepoLoader(repo, // @ts-ignore
{
branch: "main",
recursive: true,
unknown: "warn",
// @ts-ignore
branch: "main", recursive: true, unknown: "warn", // @ts-ignore
// ignorePaths: ['node_modules', 'vendor', 'bower_components', '__pycache__', '.venv', 'target', 'build', 'bin', 'obj', 'tmp', 'dist', 'public', '.git', '.svn', 'CVS', 'out', 'logs', '.idea', '.vscode', '.gradle', '.classpath', '.project', '.settings', '.DS_Store', 'venv', 'env', 'migrations', 'db', 'log', 'logs', 'backup', 'cache', 'temp', 'tmp', 'docs', 'doc', 'test', 'tests', 'spec', 'specs']
});

const rawDocs = await loader.load();

console.log('Loaded documents')

const textSplitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 200,
chunkSize: 1000, chunkOverlap: 200,
});

const docs = await textSplitter.splitDocuments(rawDocs);

console.log('Split documents')
Expand All @@ -36,17 +29,14 @@ export default async function codebaseHandler(req: NextApiRequest, res: NextApiR
const index = pinecone.Index(PINECONE_INDEX_NAME);

await PineconeStore.fromDocuments(docs, embeddings, {
pineconeIndex: index,
namespace: namespace,
textKey: 'text',
pineconeIndex: index, namespace: namespace, textKey: 'text',
});

console.log('Indexed documents. all done!')

return res.status(200).json({message: 'Success'});
} catch (e) {
console.error(e);
// @ts-ignore
res.status(500).json({error: e.message, line: e.lineNumber});
return res.status(500).json({error: e.message, line: e.lineNumber});
}
}
6 changes: 2 additions & 4 deletions llm-server/data-sources/pdfHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,14 @@ export default async function pdfHandler(req: NextApiRequest, res: NextApiRespon
const index = pinecone.Index(PINECONE_INDEX_NAME);

await PineconeStore.fromDocuments(docs, embeddings, {
pineconeIndex: index,
namespace: namespace,
textKey: 'text',
pineconeIndex: index, namespace: namespace, textKey: 'text',
});

console.log('All is done, folder deleted');
return res.status(200).json({message: 'Success'});
} catch (e) {
console.error(e);
// @ts-ignore
res.status(500).json({error: e.message, line: e.lineNumber});
return res.status(500).json({error: e.message, line: e.lineNumber});
}
}
9 changes: 3 additions & 6 deletions llm-server/data-sources/websiteHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ export default async function websiteHandler(req: NextApiRequest, res: NextApiRe
const rawDocs = await directoryLoader.load();

const textSplitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 200,
chunkSize: 1000, chunkOverlap: 200,
});

const docs = await textSplitter.splitDocuments(rawDocs);
Expand All @@ -29,15 +28,13 @@ export default async function websiteHandler(req: NextApiRequest, res: NextApiRe
const index = pinecone.Index(PINECONE_INDEX_NAME);

await PineconeStore.fromDocuments(docs, embeddings, {
pineconeIndex: index,
namespace: namespace,
textKey: 'text',
pineconeIndex: index, namespace: namespace, textKey: 'text',
});
console.log('All is done, folder deleted');
return res.status(200).json({message: 'Success'});
} catch (e) {
console.error(e);
// @ts-ignore
res.status(500).json({error: e.message, line: e.lineNumber});
return res.status(500).json({error: e.message, line: e.lineNumber});
}
}
4 changes: 2 additions & 2 deletions llm-server/declarations/pdf-parse.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
declare module 'pdf-parse/lib/pdf-parse.js' {
import pdf from 'pdf-parse';
import pdf from 'pdf-parse';

export default pdf;
export default pdf;
}
84 changes: 37 additions & 47 deletions llm-server/pages/api/chat.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,45 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { OpenAIEmbeddings } from 'langchain/embeddings/openai';
import { PineconeStore } from 'langchain/vectorstores/pinecone';
import { makeChain } from '@/utils/makechain';
import { pinecone } from '@/utils/pinecone-client';
import { PINECONE_INDEX_NAME, PINECONE_NAME_SPACE } from '@/config/pinecone';
import type {NextApiRequest, NextApiResponse} from 'next';
import {OpenAIEmbeddings} from 'langchain/embeddings/openai';
import {PineconeStore} from 'langchain/vectorstores/pinecone';
import {makeChain} from '@/utils/makechain';
import {pinecone} from '@/utils/pinecone-client';
import {PINECONE_INDEX_NAME, PINECONE_NAME_SPACE} from '@/config/pinecone';

export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const { question, history, namespace, mode, initial_prompt } = req.body;
export default async function handler(req: NextApiRequest, res: NextApiResponse,) {
const {question, history, namespace, mode, initial_prompt} = req.body;

console.log('req.body', req.body);
console.log({ question, history, namespace, mode, initial_prompt });
//only accept post requests
if (req.method !== 'POST') {
res.status(405).json({ error: 'Method not allowed' });
return;
}
console.log('req.body', req.body);
console.log({question, history, namespace, mode, initial_prompt});
//only accept post requests
if (req.method !== 'POST') {
return res.status(405).json({error: 'Method not allowed'});
}

if (!question) {
return res.status(400).json({ message: 'No question in the request' });
}
// OpenAI recommends replacing newlines with spaces for best results
const sanitizedQuestion = question.trim().replaceAll('\n', ' ');
if (!question) {
return res.status(400).json({message: 'No question in the request'});
}
// OpenAI recommends replacing newlines with spaces for best results
const sanitizedQuestion = question.trim().replaceAll('\n', ' ');

try {
const index = pinecone.Index(PINECONE_INDEX_NAME);
try {
const index = pinecone.Index(PINECONE_INDEX_NAME);

/* create vectorstore*/
const vectorStore = await PineconeStore.fromExistingIndex(
new OpenAIEmbeddings({}),
{
pineconeIndex: index,
textKey: 'text',
namespace: namespace, //namespace comes from your config folder
},
);
/* create vectorstore*/
const vectorStore = await PineconeStore.fromExistingIndex(new OpenAIEmbeddings({}), {
pineconeIndex: index, textKey: 'text', namespace: namespace, //namespace comes from your config folder
},);

//create chain
const chain = makeChain(vectorStore, mode, initial_prompt);
//Ask a question using chat history
const response = await chain.call({
question: sanitizedQuestion,
chat_history: history || [],
});
//create chain
const chain = makeChain(vectorStore, mode, initial_prompt);
//Ask a question using chat history
const response = await chain.call({
question: sanitizedQuestion, chat_history: history || [],
});

console.log('response', response);
res.status(200).json(response);
} catch (error: any) {
console.log('error', error);
res.status(500).json({ error: error.message || 'Something went wrong' });
}
console.log('response', response);
return res.status(200).json(response);
} catch (error: any) {
console.log('error', error);
return res.status(500).json({error: error.message || 'Something went wrong'});
}
}
3 changes: 2 additions & 1 deletion llm-server/pages/api/ingest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
} else {
return res.status(400).json({message: 'Not supported type'});
}

} catch (e) {
console.error(e);
// Return error message and line number
// @ts-ignore
res.status(500).json({error: e.message, line: e.lineNumber});
return res.status(500).json({error: e.message, line: e.lineNumber});
}
}
7 changes: 2 additions & 5 deletions llm-server/types/chat.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { Document } from 'langchain/document';
import {Document} from 'langchain/document';

export type Message = {
type: 'apiMessage' | 'userMessage';
message: string;
isStreaming?: boolean;
sourceDocs?: Document[];
type: 'apiMessage' | 'userMessage'; message: string; isStreaming?: boolean; sourceDocs?: Document[];
};
6 changes: 3 additions & 3 deletions llm-server/utils/cn.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
import {ClassValue, clsx} from 'clsx';
import {twMerge} from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
return twMerge(clsx(inputs));
}
88 changes: 38 additions & 50 deletions llm-server/utils/customPDFLoader.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,49 @@
import { Document } from 'langchain/document';
import { readFile } from 'fs/promises';
import { BaseDocumentLoader } from 'langchain/document_loaders';
import {Document} from 'langchain/document';
import {readFile} from 'fs/promises';
import {BaseDocumentLoader} from 'langchain/document_loaders';

export abstract class BufferLoader extends BaseDocumentLoader {
constructor(public filePathOrBlob: string | Blob) {
super();
}

protected abstract parse(
raw: Buffer,
metadata: Document['metadata'],
): Promise<Document[]>;
constructor(public filePathOrBlob: string | Blob) {
super();
}

public async load(): Promise<Document[]> {
let buffer: Buffer;
let metadata: Record<string, string>;
if (typeof this.filePathOrBlob === 'string') {
buffer = await readFile(this.filePathOrBlob);
metadata = { source: this.filePathOrBlob };
} else {
buffer = await this.filePathOrBlob
.arrayBuffer()
.then((ab) => Buffer.from(ab));
metadata = { source: 'blob', blobType: this.filePathOrBlob.type };
public async load(): Promise<Document[]> {
let buffer: Buffer;
let metadata: Record<string, string>;
if (typeof this.filePathOrBlob === 'string') {
buffer = await readFile(this.filePathOrBlob);
metadata = {source: this.filePathOrBlob};
} else {
buffer = await this.filePathOrBlob
.arrayBuffer()
.then((ab) => Buffer.from(ab));
metadata = {source: 'blob', blobType: this.filePathOrBlob.type};
}
return this.parse(buffer, metadata);
}
return this.parse(buffer, metadata);
}

protected abstract parse(raw: Buffer, metadata: Document['metadata'],): Promise<Document[]>;
}

export class CustomPDFLoader extends BufferLoader {
public async parse(
raw: Buffer,
metadata: Document['metadata'],
): Promise<Document[]> {
const { pdf } = await PDFLoaderImports();
const parsed = await pdf(raw);
return [
new Document({
pageContent: parsed.text,
metadata: {
...metadata,
pdf_numpages: parsed.numpages,
},
}),
];
}
public async parse(raw: Buffer, metadata: Document['metadata'],): Promise<Document[]> {
const {pdf} = await PDFLoaderImports();
const parsed = await pdf(raw);
return [new Document({
pageContent: parsed.text, metadata: {
...metadata, pdf_numpages: parsed.numpages,
},
}),];
}
}

async function PDFLoaderImports() {
try {
// the main entrypoint has some debug code that we don't want to import
const { default: pdf } = await import('pdf-parse/lib/pdf-parse.js');
return { pdf };
} catch (e) {
console.error(e);
throw new Error(
'Failed to load pdf-parse. Please install it with eg. `npm install pdf-parse`.',
);
}
try {
// the main entrypoint has some debug code that we don't want to import
const {default: pdf} = await import('pdf-parse/lib/pdf-parse.js');
return {pdf};
} catch (e) {
console.error(e);
throw new Error('Failed to load pdf-parse. Please install it with eg. `npm install pdf-parse`.',);
}
}
6 changes: 4 additions & 2 deletions llm-server/utils/makechain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ export const makeChain = (vectorstore: PineconeStore, mode: string, initial_prom

let enableSourceDocuments = false;

if(mode === 'pair_programmer') {
if (mode === 'pair_programmer') {
enableSourceDocuments = true;
}
return ConversationalRetrievalQAChain.fromLLM(model, vectorstore.asRetriever(), {
qaTemplate: prompts.qa_prompt, questionGeneratorTemplate: prompts.condense_prompt, returnSourceDocuments: enableSourceDocuments, //The number of source documents returned is 4 by default
qaTemplate: prompts.qa_prompt,
questionGeneratorTemplate: prompts.condense_prompt,
returnSourceDocuments: enableSourceDocuments, //The number of source documents returned is 4 by default
},);
};

Expand Down
Loading

0 comments on commit c2f99f1

Please sign in to comment.