├── public ├── favicon.ico └── screenshot.png ├── styles └── globals.css ├── postcss.config.js ├── .eslintrc.json ├── Dockerfile ├── types └── index.ts ├── tailwind.config.js ├── pages ├── _document.tsx ├── _app.tsx ├── index.tsx └── app.tsx ├── .dockerignore ├── next.config.js ├── components ├── Layout │ └── Navbar.tsx ├── Chat │ ├── ChatLoader.tsx │ ├── ResetChat.tsx │ ├── SaveChat.tsx │ ├── ChatMessage.tsx │ ├── Chat.tsx │ └── ChatInput.tsx └── Memory │ ├── UndoThoughts.tsx │ ├── CopyVectors.tsx │ ├── Context.tsx │ ├── Vectors.tsx │ └── Thoughts.tsx ├── README.md ├── .gitignore ├── tsconfig.json ├── package.json ├── license └── .github └── workflows └── docker-publish.yml /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COOORN/AssistGPT/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /public/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COOORN/AssistGPT/HEAD/public/screenshot.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals", 3 | "rules": { 4 | "react/no-unescaped-entities": "off", 5 | "@next/next/no-page-custom-font": "off" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine 2 | 3 | WORKDIR /app 4 | COPY package*.json ./ 5 | RUN npm install 6 | COPY . . 7 | RUN npx next build 8 | EXPOSE 3000 9 | CMD ["npx", "next", "start"] 10 | -------------------------------------------------------------------------------- /types/index.ts: -------------------------------------------------------------------------------- 1 | export enum OpenAIModel { 2 | DAVINCI_TURBO = "gpt-3.5-turbo" 3 | } 4 | 5 | export interface Message { 6 | role: Role; 7 | content: string; 8 | } 9 | 10 | export type Role = "assistant" | "user"; 11 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./app/**/*.{js,ts,jsx,tsx}", "./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"], 4 | theme: { 5 | extend: {} 6 | }, 7 | plugins: [], 8 | darkMode: "media", 9 | }; 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import "@/styles/globals.css"; 2 | import type { AppProps } from "next/app"; 3 | import { Inter } from "next/font/google"; 4 | 5 | const inter = Inter({ subsets: ["latin"] }); 6 | 7 | export default function App({ Component, pageProps }: AppProps<{}>) { 8 | return ( 9 |
10 | 11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/charts 15 | **/docker-compose* 16 | **/compose* 17 | **/Dockerfile* 18 | **/node_modules 19 | **/npm-debug.log 20 | **/obj 21 | **/secrets.dev.yaml 22 | **/values.dev.yaml 23 | LICENSE 24 | README.md 25 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | webpack(config) { 4 | config.experiments = { 5 | asyncWebAssembly: true, 6 | layers: true, 7 | }; 8 | 9 | return config; 10 | }, 11 | eslint: { 12 | // Warning: This allows production builds to successfully complete even if 13 | // your project has ESLint errors. 14 | ignoreDuringBuilds: true, 15 | }, 16 | }; 17 | module.exports = nextConfig 18 | 19 | -------------------------------------------------------------------------------- /components/Layout/Navbar.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | 3 | export const Navbar: FC = () => { 4 | return ( 5 | <> 6 |
7 |
8 |
9 | Assist GPT 10 |
11 |
12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A GPT client that has long term memory. 2 | ## How it works 3 | Every time a message is sent, embeddings are created and are relevent documents are retrieved(shown in the context card). 4 | There is also a persistent memory that the AI always has access to 5 | 6 | Full privacy: all completely local using localForage(an indexedDB wrapper). 7 | 8 | ### To - do not in any order: 9 | 10 | - [ ] Web browsing 11 | - [ ] Local AI - Once they make LangChain JS/TS support better, this should be possible 12 | -------------------------------------------------------------------------------- /components/Chat/ChatLoader.tsx: -------------------------------------------------------------------------------- 1 | import { IconDots } from "@tabler/icons-react"; 2 | import { FC } from "react"; 3 | 4 | interface Props {} 5 | 6 | export const ChatLoader: FC = () => { 7 | return ( 8 |
9 |
13 | 14 |
15 |
16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /components/Memory/UndoThoughts.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | 3 | interface Props { 4 | onUndo: () => void; 5 | } 6 | 7 | export const UndoThoughts: FC = ({ onUndo }) => { 8 | return ( 9 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /components/Chat/ResetChat.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | 3 | interface Props { 4 | onReset: () => void; 5 | } 6 | 7 | export const ResetChat: FC = ({ onReset }) => { 8 | return ( 9 |
10 | 16 |
17 | ); 18 | }; 19 | ; -------------------------------------------------------------------------------- /components/Chat/SaveChat.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | 3 | interface Props { 4 | onSave: () => void; 5 | loadingSave: boolean; 6 | } 7 | 8 | export const SaveChat: FC = ({ onSave, loadingSave }) => { 9 | return ( 10 | 11 | ); 12 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | .env 4 | 5 | /.vscode/ 6 | 7 | # dependencies 8 | /node_modules 9 | /.pnp 10 | .pnp.js 11 | 12 | # testing 13 | /coverage 14 | 15 | # next.js 16 | /.next/ 17 | /out/ 18 | 19 | # production 20 | /build 21 | 22 | # misc 23 | .DS_Store 24 | *.pem 25 | 26 | # debug 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | .pnpm-debug.log* 31 | 32 | # local env files 33 | .env*.local 34 | 35 | # vercel 36 | .vercel 37 | 38 | # typescript 39 | *.tsbuildinfo 40 | next-env.d.ts 41 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 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 | "paths": { 18 | "@/*": ["./*"] 19 | } 20 | }, 21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /components/Memory/CopyVectors.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | 3 | interface Props { 4 | vectors: string; 5 | } 6 | 7 | export const CopyVectors: FC = ({ vectors }) => { 8 | function handleCopy(vectors: string): void { 9 | navigator.clipboard.writeText(vectors); 10 | } 11 | 12 | return ( 13 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /components/Chat/ChatMessage.tsx: -------------------------------------------------------------------------------- 1 | import { Message } from "@/types"; 2 | import { FC } from "react"; 3 | 4 | interface Props { 5 | message: Message; 6 | } 7 | 8 | export const ChatMessage: FC = ({ message }) => { 9 | return ( 10 |
11 |
15 | {message.content} 16 |
17 |
18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "assistgpt", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@tabler/icons-react": "^2.9.0", 13 | "@types/node": "18.15.0", 14 | "@types/react": "18.0.28", 15 | "@types/react-dom": "18.0.11", 16 | "eslint": "8.36.0", 17 | "eslint-config-next": "13.2.4", 18 | "eventsource-parser": "^0.1.0", 19 | "langchain": "^0.0.61", 20 | "localforage": "^1.10.0", 21 | "next": "^13.2.4", 22 | "openai": "^3.2.1", 23 | "react": "18.2.0", 24 | "react-dom": "18.2.0", 25 | "react-markdown": "^8.0.7", 26 | "remark-gfm": "^3.0.1", 27 | "tiktoken": "^1.0.7", 28 | "typescript": "4.9.5" 29 | }, 30 | "devDependencies": { 31 | "autoprefixer": "^10.4.14", 32 | "postcss": "^8.4.21", 33 | "tailwindcss": "^3.2.7" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /components/Memory/Context.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | import { useEffect, useRef, useState } from "react"; 3 | 4 | interface Props { 5 | context: string; 6 | } 7 | 8 | export const Context: FC = ({ context }) => { 9 | const textareaRef = useRef(null); 10 | 11 | return ( 12 |
13 |
14 |

15 | Context from past memories: 16 |

17 |
18 |