├── .github
└── ISSUE_TEMPLATE
│ ├── config.yml
│ └── issue_template.yml
├── demo.gif
├── app
├── favicon.ico
├── apple-icon.png
├── opengraph-image.png
├── report
│ └── [id]
│ │ ├── page.tsx
│ │ └── report-content.tsx
├── layout.tsx
├── api
│ ├── parse-document
│ │ └── route.ts
│ ├── fetch-content
│ │ └── route.ts
│ ├── download
│ │ └── route.ts
│ ├── generate-question
│ │ └── route.ts
│ ├── optimize-research
│ │ └── route.ts
│ ├── analyze-results
│ │ └── route.ts
│ ├── consolidate-report
│ │ └── route.ts
│ ├── report
│ │ └── route.ts
│ └── search
│ │ └── route.ts
└── globals.css
├── public
├── vercel.svg
├── window.svg
├── file.svg
├── globe.svg
└── next.svg
├── next.config.ts
├── postcss.config.mjs
├── components
├── ui
│ ├── skeleton.tsx
│ ├── collapsible.tsx
│ ├── input.tsx
│ ├── separator.tsx
│ ├── toaster.tsx
│ ├── checkbox.tsx
│ ├── tooltip.tsx
│ ├── alert.tsx
│ ├── scroll-area.tsx
│ ├── tabs.tsx
│ ├── button.tsx
│ ├── card.tsx
│ ├── dialog.tsx
│ ├── sheet.tsx
│ ├── toast.tsx
│ ├── select.tsx
│ └── dropdown-menu.tsx
├── analytics.tsx
├── flow
│ ├── consolidated-edge.tsx
│ ├── question-node.tsx
│ ├── report-node.tsx
│ ├── search-node.tsx
│ ├── selection-node.tsx
│ ├── project-actions.tsx
│ └── project-selector.tsx
├── citations-footer.tsx
├── model-select.tsx
├── report-actions.tsx
└── knowledge-base-sidebar.tsx
├── Dockerfile
├── components.json
├── eslint.config.mjs
├── hooks
├── use-mobile.tsx
├── use-knowledge-base.ts
└── use-toast.ts
├── .gitignore
├── tsconfig.json
├── lib
├── redis.ts
├── gemini.ts
├── file-upload.ts
├── knowledge-base.ts
├── config.ts
├── utils.ts
├── models.ts
├── localStorage-utils.ts
└── documents.ts
├── LICENSE
├── env.example
├── package.json
├── tailwind.config.ts
├── docs
└── flow-projects.md
└── types
└── index.ts
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/btahir/open-deep-research/HEAD/demo.gif
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/btahir/open-deep-research/HEAD/app/favicon.ico
--------------------------------------------------------------------------------
/app/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/btahir/open-deep-research/HEAD/app/apple-icon.png
--------------------------------------------------------------------------------
/app/opengraph-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/btahir/open-deep-research/HEAD/app/opengraph-image.png
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | /* config options here */
5 | };
6 |
7 | export default nextConfig;
8 |
--------------------------------------------------------------------------------
/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/app/report/[id]/page.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { ReportContent } from './report-content'
3 |
4 | export default function ReportPage({ params }: any) {
5 | return
6 | }
7 |
--------------------------------------------------------------------------------
/components/ui/skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils"
2 |
3 | function Skeleton({
4 | className,
5 | ...props
6 | }: React.HTMLAttributes) {
7 | return (
8 |
12 | )
13 | }
14 |
15 | export { Skeleton }
16 |
--------------------------------------------------------------------------------
/public/window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/components/ui/collapsible.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
4 |
5 | const Collapsible = CollapsiblePrimitive.Root
6 |
7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
8 |
9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
10 |
11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent }
12 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use Node.js Alpine as the base image
2 | FROM node:20-alpine
3 |
4 | # Set the working directory
5 | WORKDIR /app
6 |
7 | # Copy package.json and package-lock.json
8 | COPY package.json package-lock.json ./
9 |
10 | # Install dependencies using npm
11 | RUN npm install
12 |
13 | # Copy the rest of the application code
14 | COPY . .
15 |
16 | # Build the application
17 | RUN npm run build
18 |
19 | # Expose the port the app runs on
20 | EXPOSE 3000
21 |
22 | # Start the application
23 | CMD ["npm", "start"]
24 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "app/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils",
16 | "ui": "@/components/ui",
17 | "lib": "@/lib",
18 | "hooks": "@/hooks"
19 | },
20 | "iconLibrary": "lucide"
21 | }
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { dirname } from 'path'
2 | import { fileURLToPath } from 'url'
3 | import { FlatCompat } from '@eslint/eslintrc'
4 |
5 | const __filename = fileURLToPath(import.meta.url)
6 | const __dirname = dirname(__filename)
7 |
8 | const compat = new FlatCompat({
9 | baseDirectory: __dirname,
10 | })
11 |
12 | const eslintConfig = [
13 | ...compat.extends('next/core-web-vitals', 'next/typescript'),
14 | {
15 | rules: {
16 | '@typescript-eslint/no-explicit-any': 'off',
17 | '@typescript-eslint/ban-ts-comment': 'off',
18 | 'prefer-rest-params': 'off',
19 | },
20 | },
21 | ]
22 |
23 | export default eslintConfig
24 |
--------------------------------------------------------------------------------
/hooks/use-mobile.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | const MOBILE_BREAKPOINT = 768
4 |
5 | export function useIsMobile() {
6 | const [isMobile, setIsMobile] = React.useState(undefined)
7 |
8 | React.useEffect(() => {
9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
10 | const onChange = () => {
11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
12 | }
13 | mql.addEventListener("change", onChange)
14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
15 | return () => mql.removeEventListener("change", onChange)
16 | }, [])
17 |
18 | return !!isMobile
19 | }
20 |
--------------------------------------------------------------------------------
/.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.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 | .pnpm-debug.log*
32 |
33 | # env files (can opt-in for committing if needed)
34 | .env*
35 |
36 | # vercel
37 | .vercel
38 |
39 | # typescript
40 | *.tsbuildinfo
41 | next-env.d.ts
42 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/components/analytics.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import Script from 'next/script'
4 |
5 | const GOOGLE_MEASUREMENT_ID =
6 | process.env.NEXT_PUBLIC_GOOGLE_MEASUREMENT_ID || ''
7 |
8 | export function Analytics() {
9 | return (
10 |