├── vrag ├── __init__.py ├── app.py ├── pdf_to_image.py ├── qdrant_client.py ├── vrag.py └── colpali.py ├── frontend ├── .eslintignore ├── src │ ├── vite-env.d.ts │ ├── App.css.ts │ ├── Question │ │ ├── Question.css.ts │ │ └── Question.tsx │ ├── theme.ts │ ├── main.tsx │ ├── ColorSchemeToggle │ │ ├── ColorSchemeToggle.css.ts │ │ └── ColorSchemeToggle.tsx │ ├── styles │ │ └── global.css.ts │ ├── Header │ │ ├── Header.css.ts │ │ └── Header.tsx │ ├── Dropzone │ │ ├── Dropzone.css.ts │ │ └── Dropzone.tsx │ ├── AttentionMap │ │ └── AttentionMap.tsx │ ├── api │ │ └── index.ts │ └── App.tsx ├── public │ ├── favicon.ico │ ├── softlandia_logo_h_white_1.png │ └── Softlandia_logo_Hor_color_small.png ├── README.md ├── tsconfig.node.json ├── vite.config.ts ├── postcss.config.cjs ├── .eslintrc.cjs ├── tsconfig.json ├── index.html ├── package.json └── .gitignore ├── requirements.txt ├── LICENSE ├── README.md ├── .gitignore └── main.py /vrag/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/.eslintignore: -------------------------------------------------------------------------------- 1 | *.js 2 | *.cjs 3 | *.mjs -------------------------------------------------------------------------------- /frontend/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /vrag/app.py: -------------------------------------------------------------------------------- 1 | from modal import App 2 | 3 | app = App(name="vision-is-all-you-need") 4 | -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Softlandia-Ltd/vision-is-all-you-need/HEAD/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/src/App.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from "@vanilla-extract/css"; 2 | 3 | export const sources = style({ 4 | overflow: "auto", 5 | }); -------------------------------------------------------------------------------- /frontend/public/softlandia_logo_h_white_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Softlandia-Ltd/vision-is-all-you-need/HEAD/frontend/public/softlandia_logo_h_white_1.png -------------------------------------------------------------------------------- /frontend/src/Question/Question.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from "@vanilla-extract/css"; 2 | 3 | export const questionInput = style({ 4 | fontSize: "1.5rem", 5 | }); 6 | -------------------------------------------------------------------------------- /frontend/public/Softlandia_logo_Hor_color_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Softlandia-Ltd/vision-is-all-you-need/HEAD/frontend/public/Softlandia_logo_Hor_color_small.png -------------------------------------------------------------------------------- /frontend/src/theme.ts: -------------------------------------------------------------------------------- 1 | import { createTheme } from "@mantine/core"; 2 | import { themeToVars } from "@mantine/vanilla-extract"; 3 | 4 | export const theme = createTheme({}); 5 | export const vars = themeToVars(theme); 6 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # Mantine + Vite + Vanilla extract template 2 | 3 | Get started with the template by clicking `Use this template` button on the top of the page. 4 | 5 | [Documentation](https://mantine.dev/styles/vanilla-extract/) 6 | -------------------------------------------------------------------------------- /frontend/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /frontend/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App.tsx"; 4 | 5 | ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( 6 | 7 | 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /frontend/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; 3 | import react from "@vitejs/plugin-react"; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react(), vanillaExtractPlugin()], 8 | }); 9 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pydantic==2.9.1 2 | qdrant-client==1.11.1 3 | pypdfium2==4.30.0 4 | fastapi[standard]==0.114.0 5 | python-dotenv==1.0.1 6 | colpali_engine==0.3.1 7 | openai==1.44.1 8 | opencv_python_headless==4.10.0.84 9 | tqdm==4.66.5 10 | transformers>=4.45.0 11 | sse-starlette==2.1.3 12 | vidore_benchmark==4.0.1 13 | einops==0.8.0 14 | torch 15 | -------------------------------------------------------------------------------- /frontend/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | "postcss-preset-mantine": {}, 4 | "postcss-simple-vars": { 5 | variables: { 6 | "mantine-breakpoint-xs": "36em", 7 | "mantine-breakpoint-sm": "48em", 8 | "mantine-breakpoint-md": "62em", 9 | "mantine-breakpoint-lg": "75em", 10 | "mantine-breakpoint-xl": "88em", 11 | }, 12 | }, 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /frontend/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { browser: true, es2020: true }, 3 | extends: [ 4 | 'eslint:recommended', 5 | 'plugin:@typescript-eslint/recommended', 6 | 'plugin:react-hooks/recommended', 7 | ], 8 | parser: '@typescript-eslint/parser', 9 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 10 | plugins: ['react-refresh'], 11 | rules: { 12 | 'react-refresh/only-export-components': 'warn', 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /frontend/src/ColorSchemeToggle/ColorSchemeToggle.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from "@vanilla-extract/css"; 2 | import { vars } from "./../theme"; 3 | 4 | export const icon = style({ 5 | width: "22px", 6 | height: "22px", 7 | }); 8 | 9 | export const dark = style({ 10 | selectors: { 11 | [vars.darkSelector]: { 12 | display: "none", 13 | }, 14 | [vars.lightSelector]: { 15 | display: "block", 16 | }, 17 | }, 18 | }); 19 | 20 | export const light = style({ 21 | selectors: { 22 | [vars.lightSelector]: { 23 | display: "none", 24 | }, 25 | [vars.darkSelector]: { 26 | display: "block", 27 | }, 28 | }, 29 | }); 30 | -------------------------------------------------------------------------------- /frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | 8 | /* Bundler mode */ 9 | "moduleResolution": "bundler", 10 | "allowImportingTsExtensions": true, 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "noEmit": true, 14 | "jsx": "react-jsx", 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"], 23 | "references": [{ "path": "./tsconfig.node.json" }] 24 | } 25 | -------------------------------------------------------------------------------- /vrag/pdf_to_image.py: -------------------------------------------------------------------------------- 1 | import pypdfium2 as pdfium 2 | import numpy as np 3 | 4 | 5 | def images_from_pdf_bytes(pdf_bytes: bytes) -> list[np.ndarray]: 6 | pdf = pdfium.PdfDocument(pdf_bytes) 7 | return images_from_document(pdf) 8 | 9 | 10 | def images_from_pdf_path(pdf_path: str) -> list[np.ndarray]: 11 | pdf = pdfium.PdfDocument(pdf_path) 12 | return images_from_document(pdf) 13 | 14 | 15 | def images_from_document(document: pdfium.PdfDocument) -> list[np.ndarray]: 16 | images = [] 17 | scale = 92 / 72 18 | 19 | for i in range(len(document)): 20 | page = document[i] 21 | img = page.render(scale=scale, rev_byteorder=True).to_numpy() # type: ignore 22 | images.append(img) 23 | 24 | return images 25 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | Vision All You Need by Softlandia 11 | 12 | 13 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /frontend/src/ColorSchemeToggle/ColorSchemeToggle.tsx: -------------------------------------------------------------------------------- 1 | import { ActionIcon, Tooltip, useMantineColorScheme } from "@mantine/core"; 2 | import { IconSun, IconMoon } from "@tabler/icons-react"; 3 | import cx from "clsx"; 4 | import * as classes from "./ColorSchemeToggle.css"; 5 | 6 | export function ColorSchemeToggle() { 7 | const { setColorScheme, colorScheme } = useMantineColorScheme(); 8 | 9 | return ( 10 | 13 | 15 | setColorScheme(colorScheme === "light" ? "dark" : "light") 16 | } 17 | variant="default" 18 | size="lg" 19 | aria-label="Toggle color scheme" 20 | > 21 | 22 | 23 | 24 | 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /frontend/src/styles/global.css.ts: -------------------------------------------------------------------------------- 1 | import { globalStyle } from "@vanilla-extract/css"; 2 | 3 | // Default style resets 4 | 5 | globalStyle("html, body", { 6 | margin: 0, 7 | padding: 0, 8 | minHeight: "100vh", 9 | height: "100%", 10 | fontFamily: "'Quicksand', sans-serif", 11 | }); 12 | 13 | globalStyle("h1, h2, h3, h4, h5, h6, p, a, span, label, div", { 14 | fontWeight: "inherit", 15 | fontSize: "inherit", 16 | color: "inherit", 17 | textDecoration: "none", 18 | margin: 0, 19 | padding: 0, 20 | fontFamily: "'Quicksand', sans-serif", 21 | }); 22 | 23 | globalStyle("button", { 24 | WebkitTouchCallout: "none", // iOS Safari 25 | WebkitUserSelect: "none", // Safari 26 | MozUserSelect: "none", // Old versions of Firefox 27 | msUserSelect: "none", // Internet Explorer / Edge 28 | userSelect: "none", // Chrome, Edge, Opera and Firefox 29 | }); 30 | 31 | // Root styles 32 | 33 | globalStyle("#root", { 34 | height: "100%", 35 | fontFamily: "'Quicksand', sans-serif", 36 | }); 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Softlandia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /frontend/src/Header/Header.css.ts: -------------------------------------------------------------------------------- 1 | import { style } from "@vanilla-extract/css"; 2 | import { vars } from "../theme"; 3 | import { rem } from "@mantine/core"; 4 | 5 | export const title = style({ 6 | color: vars.colors.black, 7 | fontSize: rem(50), 8 | fontWeight: 900, 9 | letterSpacing: rem(-2), 10 | selectors: { 11 | [vars.darkSelector]: { 12 | color: vars.colors.white, 13 | }, 14 | }, 15 | 16 | "@media": { 17 | [vars.smallerThan("md")]: { 18 | fontSize: rem(25), 19 | }, 20 | [vars.smallerThan("sm")]: { 21 | fontSize: rem(20), 22 | }, 23 | }, 24 | }); 25 | 26 | export const header = style({ 27 | height: 60, 28 | backgroundColor: vars.colors.body, 29 | borderBottom: `1px solid ${vars.colors.gray[3]}`, 30 | borderBottomColor: vars.colors.gray[3], 31 | display: "flex", 32 | justifyContent: "center", 33 | alignItems: "center", 34 | paddingBottom: 5, 35 | selectors: { 36 | [vars.darkSelector]: { 37 | borderBottomColor: vars.colors.dark[4], 38 | }, 39 | }, 40 | "@media": { 41 | [vars.smallerThan("md")]: { 42 | height: 90, 43 | paddingBottom: 10, 44 | }, 45 | [vars.smallerThan("sm")]: { 46 | height: 90, 47 | paddingBottom: 10, 48 | }, 49 | }, 50 | }); 51 | -------------------------------------------------------------------------------- /frontend/src/Question/Question.tsx: -------------------------------------------------------------------------------- 1 | import { Textarea, ActionIcon, useMantineTheme, rem } from "@mantine/core"; 2 | import { IconArrowRight } from "@tabler/icons-react"; 3 | import { useState } from "react"; 4 | import * as classes from "./Question.css"; 5 | 6 | 7 | export interface QuestionProps { 8 | onSubmit: (question: string) => void; 9 | loading: boolean; 10 | disabled: boolean; 11 | } 12 | 13 | export function Question(props: QuestionProps) { 14 | const theme = useMantineTheme(); 15 | const [question, setQuestion] = useState(""); 16 | 17 | return ( 18 |