├── 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 |