├── .eslintrc.json ├── styles ├── base.css ├── chrome-bug.css ├── loading-dots.module.css └── Home.module.css ├── public ├── favicon.ico ├── bot-image.png └── usericon.png ├── .prettierrc ├── postcss.config.cjs ├── visual-guide └── gpt-langchain-pdf.png ├── declarations └── pdf-parse.d.ts ├── utils ├── cn.ts ├── openai-client.ts ├── pinecone-client.ts └── makechain.ts ├── .env.example ├── types └── chat.ts ├── tailwind.config.cjs ├── pages ├── _document.tsx ├── _app.tsx ├── api │ └── chat.ts └── index.tsx ├── next.config.js ├── config └── pinecone.ts ├── components ├── ui │ ├── LoadingDots.tsx │ ├── TextArea.tsx │ └── accordion.tsx └── layout.tsx ├── .gitignore ├── tsconfig.json ├── package.json ├── scripts └── ingest-data.ts └── README.md /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /styles/base.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misbahsy/chat-with-twitter-algorithm/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/bot-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misbahsy/chat-with-twitter-algorithm/HEAD/public/bot-image.png -------------------------------------------------------------------------------- /public/usericon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misbahsy/chat-with-twitter-algorithm/HEAD/public/usericon.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "all", 3 | "singleQuote": true, 4 | "printWidth": 80, 5 | "tabWidth": 2 6 | } 7 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /visual-guide/gpt-langchain-pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misbahsy/chat-with-twitter-algorithm/HEAD/visual-guide/gpt-langchain-pdf.png -------------------------------------------------------------------------------- /declarations/pdf-parse.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'pdf-parse/lib/pdf-parse.js' { 2 | import pdf from 'pdf-parse'; 3 | 4 | export default pdf; 5 | } 6 | -------------------------------------------------------------------------------- /utils/cn.ts: -------------------------------------------------------------------------------- 1 | import { ClassValue, clsx } from 'clsx'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | 3 | # Update these with your Supabase details from your project settings > API and dashboard settings 4 | PINECONE_API_KEY= 5 | PINECONE_ENVIRONMENT= 6 | PINECONE_INDEX_NAME= 7 | -------------------------------------------------------------------------------- /types/chat.ts: -------------------------------------------------------------------------------- 1 | import { Document } from 'langchain/document'; 2 | 3 | export type Message = { 4 | type: 'apiMessage' | 'userMessage'; 5 | message: string; 6 | isStreaming?: boolean; 7 | sourceDocs?: Document[]; 8 | }; 9 | -------------------------------------------------------------------------------- /utils/openai-client.ts: -------------------------------------------------------------------------------- 1 | import { OpenAI } from 'langchain/llms'; 2 | 3 | if (!process.env.OPENAI_API_KEY) { 4 | throw new Error('Missing OpenAI Credentials'); 5 | } 6 | 7 | export const openai = new OpenAI({ 8 | temperature: 0, 9 | }); 10 | -------------------------------------------------------------------------------- /tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './app/**/*.{js,ts,jsx,tsx}', 5 | './pages/**/*.{js,ts,jsx,tsx}', 6 | './components/**/*.{js,ts,jsx,tsx}', 7 | ], 8 | theme: { 9 | extend: {}, 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from "next/document"; 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | swcMinify: true, 5 | webpack(config) { 6 | config.experiments = { ...config.experiments, topLevelAwait: true }; 7 | return config; 8 | }, 9 | }; 10 | 11 | export default nextConfig; 12 | -------------------------------------------------------------------------------- /styles/chrome-bug.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Chrome has a bug with transitions on load since 2012! 3 | * 4 | * To prevent a "pop" of content, you have to disable all transitions until 5 | * the page is done loading. 6 | * 7 | * https://lab.laukstein.com/bug/input 8 | * https://twitter.com/timer150/status/1345217126680899584 9 | */ 10 | body.loading * { 11 | transition: none !important; 12 | } 13 | -------------------------------------------------------------------------------- /config/pinecone.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Change the namespace to the namespace on Pinecone you'd like to store your embeddings. 3 | */ 4 | 5 | if (!process.env.PINECONE_INDEX_NAME) { 6 | throw new Error('Missing Pinecone index name in .env file'); 7 | } 8 | 9 | const PINECONE_INDEX_NAME = process.env.PINECONE_INDEX_NAME ?? ''; 10 | 11 | const PINECONE_NAME_SPACE = 'the-algorithm'; //namespace is optional for your vectors 12 | 13 | export { PINECONE_INDEX_NAME, PINECONE_NAME_SPACE }; 14 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '@/styles/base.css'; 2 | import type { AppProps } from 'next/app'; 3 | import { Inter } from 'next/font/google'; 4 | 5 | const inter = Inter({ 6 | variable: '--font-inter', 7 | subsets: ['latin'], 8 | }); 9 | 10 | function MyApp({ Component, pageProps }: AppProps) { 11 | return ( 12 | <> 13 |
14 | 15 |
16 | 17 | ); 18 | } 19 | 20 | export default MyApp; 21 | -------------------------------------------------------------------------------- /components/ui/LoadingDots.tsx: -------------------------------------------------------------------------------- 1 | import styles from '@/styles/loading-dots.module.css'; 2 | 3 | const LoadingDots = ({ 4 | color = '#000', 5 | style = 'small', 6 | }: { 7 | color: string; 8 | style: string; 9 | }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | }; 18 | 19 | export default LoadingDots; 20 | 21 | LoadingDots.defaultProps = { 22 | style: 'small', 23 | }; 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | .env 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | 39 | #Notion_db 40 | /Notion_DB 41 | 42 | #replit 43 | replit.nix 44 | .replit -------------------------------------------------------------------------------- /utils/pinecone-client.ts: -------------------------------------------------------------------------------- 1 | import { PineconeClient } from '@pinecone-database/pinecone'; 2 | 3 | if (!process.env.PINECONE_ENVIRONMENT || !process.env.PINECONE_API_KEY) { 4 | throw new Error('Pinecone environment or api key vars missing'); 5 | } 6 | 7 | async function initPinecone() { 8 | try { 9 | const pinecone = new PineconeClient(); 10 | 11 | await pinecone.init({ 12 | environment: process.env.PINECONE_ENVIRONMENT ?? '', //this is in the dashboard 13 | apiKey: process.env.PINECONE_API_KEY ?? '', 14 | }); 15 | 16 | return pinecone; 17 | } catch (error) { 18 | console.log('error', error); 19 | throw new Error('Failed to initialize Pinecone Client'); 20 | } 21 | } 22 | 23 | export const pinecone = await initPinecone(); 24 | -------------------------------------------------------------------------------- /components/layout.tsx: -------------------------------------------------------------------------------- 1 | interface LayoutProps { 2 | children?: React.ReactNode; 3 | } 4 | 5 | export default function Layout({ children }: LayoutProps) { 6 | return ( 7 |
8 |
9 |
10 | 15 |
16 |
17 |
18 |
19 | {children} 20 |
21 |
22 |
23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "baseUrl": ".", 18 | "plugins": [ 19 | { 20 | "name": "next" 21 | } 22 | ], 23 | "paths": { 24 | "@/*": ["./*"] 25 | } 26 | }, 27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 28 | "exclude": ["node_modules"] 29 | } 30 | -------------------------------------------------------------------------------- /components/ui/TextArea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { cn } from '@/utils/cn'; 3 | 4 | export interface TextareaProps 5 | extends React.TextareaHTMLAttributes {} 6 | 7 | const Textarea = React.forwardRef( 8 | ({ className, ...props }, ref) => { 9 | return ( 10 |