├── embedding_model └── .ignore ├── .gitignore ├── front-end ├── .vscode │ └── extensions.json ├── src │ ├── vite-env.d.ts │ ├── assets │ │ ├── images │ │ │ ├── bot.jpeg │ │ │ └── me.jpeg │ │ └── svelte.svg │ ├── main.js │ ├── lib │ │ ├── MdLink.svelte │ │ ├── generation.store.js │ │ ├── External.svelte │ │ ├── Modal.svelte │ │ └── chat.store.js │ ├── app.css │ └── App.svelte ├── postcss.config.js ├── svelte.config.js ├── tailwind.config.js ├── vite.config.js ├── .gitignore ├── index.html ├── package.json ├── jsconfig.json ├── public │ └── vite.svg ├── README.md └── package-lock.json ├── images └── datamodel.png ├── .dockerignore ├── .github └── media │ ├── app3-ui.png │ ├── app5-ui.png │ ├── app1-ticket.png │ ├── app2-model.png │ ├── app2-ui-1.png │ ├── app1-concept.png │ ├── app1-generate.png │ └── app1-rag-selector.png ├── front-end.Dockerfile ├── requirements.txt ├── api.Dockerfile ├── bot.Dockerfile ├── pdf_bot.Dockerfile ├── loader.Dockerfile ├── pull_model.Dockerfile ├── env.example ├── utils.py ├── pdf_bot.py ├── api.py ├── bot.py ├── loader.py ├── LICENSE ├── docker-compose.yml ├── readme.md ├── chains.py └── CONTRIBUTING.md /embedding_model/.ignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | data/ 3 | embedding_model/* 4 | !embedding_model/.ignore 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /front-end/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["svelte.svelte-vscode"] 3 | } 4 | -------------------------------------------------------------------------------- /images/datamodel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/images/datamodel.png -------------------------------------------------------------------------------- /front-end/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !*.py 3 | !requirements.txt 4 | !images/* 5 | !front-end/* 6 | front-end/node_modules/* 7 | -------------------------------------------------------------------------------- /.github/media/app3-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/.github/media/app3-ui.png -------------------------------------------------------------------------------- /.github/media/app5-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/.github/media/app5-ui.png -------------------------------------------------------------------------------- /.github/media/app1-ticket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/.github/media/app1-ticket.png -------------------------------------------------------------------------------- /.github/media/app2-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/.github/media/app2-model.png -------------------------------------------------------------------------------- /.github/media/app2-ui-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/.github/media/app2-ui-1.png -------------------------------------------------------------------------------- /.github/media/app1-concept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/.github/media/app1-concept.png -------------------------------------------------------------------------------- /.github/media/app1-generate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/.github/media/app1-generate.png -------------------------------------------------------------------------------- /.github/media/app1-rag-selector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/.github/media/app1-rag-selector.png -------------------------------------------------------------------------------- /front-end/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /front-end/src/assets/images/bot.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/front-end/src/assets/images/bot.jpeg -------------------------------------------------------------------------------- /front-end/src/assets/images/me.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidagarwal04/genai-stack/main/front-end/src/assets/images/me.jpeg -------------------------------------------------------------------------------- /front-end.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | 3 | WORKDIR /app 4 | 5 | COPY front-end/ . 6 | 7 | RUN npm install 8 | 9 | EXPOSE 8505 10 | 11 | ENTRYPOINT [ "npm", "run", "dev" ] 12 | -------------------------------------------------------------------------------- /front-end/src/main.js: -------------------------------------------------------------------------------- 1 | import './app.css' 2 | import App from './App.svelte' 3 | 4 | const app = new App({ 5 | target: document.getElementById('app'), 6 | }) 7 | 8 | export default app 9 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | openai==0.28.1 2 | python-dotenv 3 | wikipedia 4 | tiktoken 5 | neo4j 6 | streamlit 7 | sentence_transformers==2.2.2 8 | Pillow 9 | fastapi 10 | PyPDF2 11 | torch==2.0.1 12 | pydantic 13 | uvicorn 14 | sse-starlette 15 | boto3 16 | -------------------------------------------------------------------------------- /front-end/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' 2 | 3 | export default { 4 | // Consult https://svelte.dev/docs#compile-time-svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: vitePreprocess(), 7 | } 8 | -------------------------------------------------------------------------------- /front-end/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{svelte,js,ts,jsx,tsx}", 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | } 12 | 13 | -------------------------------------------------------------------------------- /front-end/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import { svelte } from '@sveltejs/vite-plugin-svelte' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | server: { 7 | host: '0.0.0.0', 8 | port: 8505, 9 | }, 10 | plugins: [svelte()], 11 | }) 12 | -------------------------------------------------------------------------------- /front-end/src/lib/MdLink.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | {text} 8 | 9 | 15 | -------------------------------------------------------------------------------- /front-end/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /front-end/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Support bot application 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /front-end/src/app.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | margin: 0; 7 | min-width: 320px; 8 | height: 100dvh; 9 | } 10 | 11 | #app { 12 | height: 100%; 13 | } 14 | 15 | pre { 16 | line-height: 1; 17 | background-color: rgb(241, 241, 241); 18 | padding: 4px 8px 8px; 19 | border: 1px solid #ccc; 20 | overflow-x: auto; 21 | margin: 0 4px; 22 | border-radius: 2px; 23 | } 24 | 25 | ol { 26 | padding: 1em; 27 | list-style: decimal; 28 | } 29 | -------------------------------------------------------------------------------- /api.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM langchain/langchain 2 | 3 | WORKDIR /app 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | build-essential \ 7 | curl \ 8 | software-properties-common \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | COPY requirements.txt . 12 | 13 | RUN pip install --upgrade -r requirements.txt 14 | 15 | COPY api.py . 16 | COPY utils.py . 17 | COPY chains.py . 18 | 19 | HEALTHCHECK CMD curl --fail http://localhost:8504 20 | 21 | ENTRYPOINT [ "uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8504" ] 22 | -------------------------------------------------------------------------------- /front-end/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bot-ui", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "@sveltejs/vite-plugin-svelte": "^2.4.2", 13 | "autoprefixer": "^10.4.16", 14 | "postcss": "^8.4.31", 15 | "svelte": "^4.0.5", 16 | "tailwindcss": "^3.3.3", 17 | "vite": "^4.4.5" 18 | }, 19 | "dependencies": { 20 | "svelte-markdown": "^0.4.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /bot.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM langchain/langchain 2 | 3 | WORKDIR /app 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | build-essential \ 7 | curl \ 8 | software-properties-common \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | COPY requirements.txt . 12 | 13 | RUN pip install --upgrade -r requirements.txt 14 | 15 | COPY bot.py . 16 | COPY utils.py . 17 | COPY chains.py . 18 | 19 | EXPOSE 8501 20 | 21 | HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health 22 | 23 | ENTRYPOINT ["streamlit", "run", "bot.py", "--server.port=8501", "--server.address=0.0.0.0"] 24 | -------------------------------------------------------------------------------- /pdf_bot.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM langchain/langchain 2 | 3 | WORKDIR /app 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | build-essential \ 7 | curl \ 8 | software-properties-common \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | COPY requirements.txt . 12 | 13 | RUN pip install --upgrade -r requirements.txt 14 | 15 | COPY pdf_bot.py . 16 | COPY utils.py . 17 | COPY chains.py . 18 | 19 | EXPOSE 8503 20 | 21 | HEALTHCHECK CMD curl --fail http://localhost:8503/_stcore/health 22 | 23 | ENTRYPOINT ["streamlit", "run", "pdf_bot.py", "--server.port=8503", "--server.address=0.0.0.0"] 24 | -------------------------------------------------------------------------------- /loader.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM langchain/langchain 2 | 3 | WORKDIR /app 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | build-essential \ 7 | curl \ 8 | software-properties-common \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | COPY requirements.txt . 12 | 13 | RUN pip install --upgrade -r requirements.txt 14 | 15 | COPY loader.py . 16 | COPY utils.py . 17 | COPY chains.py . 18 | COPY images ./images 19 | 20 | EXPOSE 8502 21 | 22 | HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health 23 | 24 | ENTRYPOINT ["streamlit", "run", "loader.py", "--server.port=8502", "--server.address=0.0.0.0"] 25 | -------------------------------------------------------------------------------- /front-end/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "bundler", 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | /** 7 | * svelte-preprocess cannot figure out whether you have 8 | * a value or a type, so tell TypeScript to enforce using 9 | * `import type` instead of `import` for Types. 10 | */ 11 | "verbatimModuleSyntax": true, 12 | "isolatedModules": true, 13 | "resolveJsonModule": true, 14 | /** 15 | * To have warnings / errors of the Svelte compiler at the 16 | * correct position, enable source maps by default. 17 | */ 18 | "sourceMap": true, 19 | "esModuleInterop": true, 20 | "skipLibCheck": true, 21 | /** 22 | * Typecheck JS in `.svelte` and `.js` files by default. 23 | * Disable this if you'd like to use dynamic types. 24 | */ 25 | "checkJs": true 26 | }, 27 | /** 28 | * Use global.d.ts instead of compilerOptions.types 29 | * to avoid limiting type declarations. 30 | */ 31 | "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"] 32 | } 33 | -------------------------------------------------------------------------------- /front-end/src/lib/generation.store.js: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | const API_ENDPOINT = "http://localhost:8504/generate-ticket"; 4 | 5 | export const generationStates = { 6 | IDLE: "idle", 7 | SUCCESS: "success", 8 | ERROR: "error", 9 | LOADING: "loading", 10 | }; 11 | 12 | function createGenerationStore() { 13 | const { subscribe, update } = writable({ state: generationStates.IDLE, data: { title: "", text: "" } }); 14 | 15 | return { 16 | subscribe, 17 | generate: async (fromQuestion) => { 18 | update(() => ({ state: generationStates.LOADING, data: { title: "", text: "" } })); 19 | try { 20 | const response = await fetch(`${API_ENDPOINT}?text=${encodeURI(fromQuestion)}`, { 21 | method: "GET", 22 | }); 23 | const generation = await response.json(); 24 | update(() => ({ state: generationStates.SUCCESS, data: generation.result })); 25 | } catch (e) { 26 | console.log("e: ", e); 27 | update(() => ({ state: generationStates.ERROR, data: { title: "", text: "" } })); 28 | } 29 | }, 30 | }; 31 | } 32 | 33 | export const generationStore = createGenerationStore(); 34 | -------------------------------------------------------------------------------- /front-end/src/lib/External.svelte: -------------------------------------------------------------------------------- 1 |
2 | 8 | 9 | 16 | 17 | 19 |
20 | 21 | 29 | -------------------------------------------------------------------------------- /front-end/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pull_model.Dockerfile: -------------------------------------------------------------------------------- 1 | #syntax = docker/dockerfile:1.4 2 | 3 | FROM ollama/ollama:latest AS ollama 4 | FROM babashka/babashka:latest 5 | 6 | # just using as a client - never as a server 7 | COPY --from=ollama /bin/ollama ./bin/ollama 8 | 9 | COPY <!! done :stop)) 31 | 32 | (println "OLLAMA model only pulled if both LLM and OLLAMA_BASE_URL are set and the LLM model is not gpt"))) 33 | (catch Throwable _ (System/exit 1))) 34 | EOF 35 | 36 | ENTRYPOINT ["bb", "-f", "pull_model.clj"] 37 | 38 | -------------------------------------------------------------------------------- /env.example: -------------------------------------------------------------------------------- 1 | #***************************************************************** 2 | # LLM and Embedding Model 3 | #***************************************************************** 4 | LLM=llama2 #or any Ollama model tag, gpt-4, gpt-3.5, or claudev2 5 | EMBEDDING_MODEL=sentence_transformer #or openai, ollama, or aws 6 | 7 | #***************************************************************** 8 | # Neo4j 9 | #***************************************************************** 10 | #NEO4J_URI=neo4j://database:7687 11 | #NEO4J_USERNAME=neo4j 12 | #NEO4J_PASSWORD=password 13 | 14 | #***************************************************************** 15 | # Langchain 16 | #***************************************************************** 17 | # Optional for enabling Langchain Smith API 18 | 19 | #LANGCHAIN_TRACING_V2=true # false 20 | #LANGCHAIN_ENDPOINT="https://api.smith.langchain.com" 21 | #LANGCHAIN_PROJECT=#your-project-name 22 | #LANGCHAIN_API_KEY=#your-api-key ls_... 23 | 24 | #***************************************************************** 25 | # Ollama 26 | #***************************************************************** 27 | #OLLAMA_BASE_URL=http://host.docker.internal:11434 28 | 29 | #***************************************************************** 30 | # OpenAI 31 | #***************************************************************** 32 | # Only required when using OpenAI LLM or embedding model 33 | 34 | #OPENAI_API_KEY=sk-... 35 | 36 | #***************************************************************** 37 | # AWS 38 | #***************************************************************** 39 | # Only required when using AWS Bedrock LLM or embedding model 40 | 41 | #AWS_ACCESS_KEY_ID= 42 | #AWS_SECRET_ACCESS_KEY= 43 | #AWS_DEFAULT_REGION=us-east-1 -------------------------------------------------------------------------------- /front-end/src/assets/svelte.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | class BaseLogger: 2 | def __init__(self) -> None: 3 | self.info = print 4 | 5 | 6 | def extract_title_and_question(input_string): 7 | lines = input_string.strip().split("\n") 8 | 9 | title = "" 10 | question = "" 11 | is_question = False # flag to know if we are inside a "Question" block 12 | 13 | for line in lines: 14 | if line.startswith("Title:"): 15 | title = line.split("Title: ", 1)[1].strip() 16 | elif line.startswith("Question:"): 17 | question = line.split("Question: ", 1)[1].strip() 18 | is_question = ( 19 | True # set the flag to True once we encounter a "Question:" line 20 | ) 21 | elif is_question: 22 | # if the line does not start with "Question:" but we are inside a "Question" block, 23 | # then it is a continuation of the question 24 | question += "\n" + line.strip() 25 | 26 | return title, question 27 | 28 | 29 | def create_vector_index(driver, dimension: int) -> None: 30 | index_query = "CALL db.index.vector.createNodeIndex('stackoverflow', 'Question', 'embedding', $dimension, 'cosine')" 31 | try: 32 | driver.query(index_query, {"dimension": dimension}) 33 | except: # Already exists 34 | pass 35 | index_query = "CALL db.index.vector.createNodeIndex('top_answers', 'Answer', 'embedding', $dimension, 'cosine')" 36 | try: 37 | driver.query(index_query, {"dimension": dimension}) 38 | except: # Already exists 39 | pass 40 | 41 | 42 | def create_constraints(driver): 43 | driver.query( 44 | "CREATE CONSTRAINT question_id IF NOT EXISTS FOR (q:Question) REQUIRE (q.id) IS UNIQUE" 45 | ) 46 | driver.query( 47 | "CREATE CONSTRAINT answer_id IF NOT EXISTS FOR (a:Answer) REQUIRE (a.id) IS UNIQUE" 48 | ) 49 | driver.query( 50 | "CREATE CONSTRAINT user_id IF NOT EXISTS FOR (u:User) REQUIRE (u.id) IS UNIQUE" 51 | ) 52 | driver.query( 53 | "CREATE CONSTRAINT tag_name IF NOT EXISTS FOR (t:Tag) REQUIRE (t.name) IS UNIQUE" 54 | ) 55 | -------------------------------------------------------------------------------- /front-end/src/lib/Modal.svelte: -------------------------------------------------------------------------------- 1 | 20 | 21 | 25 |
26 |
27 |

Create new internal ticket

28 |
29 | 33 |
34 |
35 |