├── .cursorrules ├── .dockerignore ├── .env.example ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── docker-build.yml │ └── docker-push.yml ├── .gitignore ├── .python-version ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CURSOR_RULES.md ├── Dockerfile ├── LICENSE ├── Procfile ├── README-ja_JP.md ├── README-ko_KR.md ├── README-zh_CN.md ├── README.md ├── backend ├── __init__.py ├── chat │ ├── __init__.py │ └── chat.py ├── memory │ ├── __init__.py │ ├── draft.py │ └── research.py ├── report_type │ ├── __init__.py │ ├── basic_report │ │ ├── __init__.py │ │ └── basic_report.py │ ├── deep_research │ │ ├── README.md │ │ ├── __init__.py │ │ ├── example.py │ │ └── main.py │ └── detailed_report │ │ ├── README.md │ │ ├── __init__.py │ │ └── detailed_report.py ├── server │ ├── __init__.py │ ├── app.py │ ├── logging_config.py │ ├── server.py │ ├── server_utils.py │ └── websocket_manager.py └── utils.py ├── citation.cff ├── cli.py ├── docker-compose.yml ├── docs ├── CNAME ├── README.md ├── babel.config.js ├── blog │ ├── 2023-09-22-gpt-researcher │ │ ├── architecture.png │ │ ├── index.md │ │ └── planner.jpeg │ ├── 2023-11-12-openai-assistant │ │ ├── diagram-1.png │ │ ├── diagram-assistant.jpeg │ │ └── index.md │ ├── 2024-05-19-gptr-langgraph │ │ ├── architecture.jpeg │ │ ├── blog-langgraph.jpeg │ │ └── index.md │ ├── 2024-09-7-hybrid-research │ │ ├── gptr-hybrid.png │ │ └── index.md │ ├── 2025-02-26-deep-research │ │ └── index.md │ ├── 2025-03-10-stepping-into-the-story │ │ └── index.md │ └── authors.yml ├── discord-bot │ ├── Dockerfile │ ├── Dockerfile.dev │ ├── commands │ │ └── ask.js │ ├── deploy-commands.js │ ├── gptr-webhook.js │ ├── index.js │ ├── package.json │ └── server.js ├── docs │ ├── contribute.md │ ├── examples │ │ ├── custom_prompt.py │ │ ├── detailed_report.md │ │ ├── examples.ipynb │ │ ├── examples.md │ │ ├── hybrid_research.md │ │ ├── pip-run.ipynb │ │ ├── sample_report.py │ │ └── sample_sources_only.py │ ├── faq.md │ ├── gpt-researcher │ │ ├── context │ │ │ ├── azure-storage.md │ │ │ ├── data-ingestion.md │ │ │ ├── filtering-by-domain.md │ │ │ ├── img │ │ │ │ ├── gptr-hybrid.png │ │ │ │ ├── nextjs-filter-by-domain.JPG │ │ │ │ └── vanilla-filter-by-domains.png │ │ │ ├── local-docs.md │ │ │ ├── tailored-research.md │ │ │ └── vector-stores.md │ │ ├── frontend │ │ │ ├── discord-bot.md │ │ │ ├── embed-script.md │ │ │ ├── img │ │ │ │ ├── bot-permissions.png │ │ │ │ └── oath2-url-generator.png │ │ │ ├── introduction.md │ │ │ ├── nextjs-frontend.md │ │ │ ├── react-package.md │ │ │ ├── vanilla-js-frontend.md │ │ │ └── visualizing-websockets.md │ │ ├── getting-started │ │ │ ├── cli.md │ │ │ ├── getting-started-with-docker.md │ │ │ ├── getting-started.md │ │ │ ├── how-to-choose.md │ │ │ ├── introduction.md │ │ │ └── linux-deployment.md │ │ ├── gptr │ │ │ ├── automated-tests.md │ │ │ ├── config.md │ │ │ ├── deep_research.md │ │ │ ├── example.md │ │ │ ├── npm-package.md │ │ │ ├── pip-package.md │ │ │ ├── querying-the-backend.md │ │ │ ├── scraping.md │ │ │ └── troubleshooting.md │ │ ├── handling-logs │ │ │ ├── all-about-logs.md │ │ │ ├── langsmith-logs.md │ │ │ ├── langsmith.png │ │ │ └── simple-logs-example.md │ │ ├── llms │ │ │ ├── llms.md │ │ │ ├── running-with-azure.md │ │ │ ├── running-with-ollama.md │ │ │ ├── supported-llms.md │ │ │ └── testing-your-llm.md │ │ ├── mcp-server │ │ │ ├── advanced-usage.md │ │ │ ├── claude-integration.md │ │ │ └── getting-started.md │ │ ├── multi_agents │ │ │ └── langgraph.md │ │ └── search-engines │ │ │ ├── retrievers.md │ │ │ └── test-your-retriever.md │ ├── reference │ │ ├── config │ │ │ ├── config.md │ │ │ └── singleton.md │ │ ├── processing │ │ │ ├── html.md │ │ │ └── text.md │ │ └── sidebar.json │ ├── roadmap.md │ └── welcome.md ├── docusaurus.config.js ├── npm │ ├── Readme.md │ ├── index.js │ └── package.json ├── package.json ├── pydoc-markdown.yml ├── sidebars.js ├── src │ ├── components │ │ ├── HomepageFeatures.js │ │ └── HomepageFeatures.module.css │ ├── css │ │ └── custom.css │ └── pages │ │ ├── index.js │ │ └── index.module.css └── static │ ├── .nojekyll │ ├── CNAME │ └── img │ ├── architecture.png │ ├── banner1.jpg │ ├── examples.png │ ├── gptr-logo.png │ ├── leaderboard.png │ └── multi-agent.png ├── evals ├── README.md ├── __init__.py └── simple_evals │ ├── .gitignore │ ├── __init__.py │ ├── logs │ ├── .gitkeep │ ├── README.md │ └── SimpleQA Eval 100 Problems 2-22-25.txt │ ├── problems │ └── Simple QA Test Set.csv │ ├── requirements.txt │ ├── run_eval.py │ └── simpleqa_eval.py ├── frontend ├── README.md ├── index.html ├── nextjs │ ├── .babelrc.build.json │ ├── .dockerignore │ ├── .eslintrc.json │ ├── .example.env │ ├── .gitignore │ ├── .prettierrc │ ├── Dockerfile │ ├── Dockerfile.dev │ ├── README.md │ ├── actions │ │ └── apiActions.ts │ ├── app │ │ ├── globals.css │ │ ├── layout.tsx │ │ └── page.tsx │ ├── components │ │ ├── Footer.tsx │ │ ├── Header.tsx │ │ ├── Hero.tsx │ │ ├── HumanFeedback.tsx │ │ ├── Images │ │ │ ├── ImageModal.tsx │ │ │ └── ImagesAlbum.tsx │ │ ├── Langgraph │ │ │ └── Langgraph.js │ │ ├── LoadingDots.tsx │ │ ├── ResearchBlocks │ │ │ ├── AccessReport.tsx │ │ │ ├── Answer.tsx │ │ │ ├── ImageSection.tsx │ │ │ ├── LogsSection.tsx │ │ │ ├── Question.tsx │ │ │ ├── Sources.tsx │ │ │ └── elements │ │ │ │ ├── InputArea.tsx │ │ │ │ ├── LogMessage.tsx │ │ │ │ ├── SourceCard.tsx │ │ │ │ └── SubQuestions.tsx │ │ ├── ResearchResults.tsx │ │ ├── ResearchSidebar.tsx │ │ ├── Settings │ │ │ ├── ChatBox.tsx │ │ │ ├── FileUpload.tsx │ │ │ ├── Modal.tsx │ │ │ ├── Settings.css │ │ │ └── ToneSelector.tsx │ │ ├── SimilarTopics.tsx │ │ ├── Task │ │ │ ├── Accordion.tsx │ │ │ ├── AgentLogs.tsx │ │ │ ├── Report.tsx │ │ │ └── ResearchForm.tsx │ │ └── TypeAnimation.tsx │ ├── config │ │ └── task.ts │ ├── helpers │ │ ├── findDifferences.ts │ │ ├── getHost.ts │ │ └── markdownHelper.ts │ ├── hooks │ │ ├── useAnalytics.ts │ │ ├── useResearchHistory.ts │ │ └── useWebSocket.ts │ ├── next.config.mjs │ ├── nginx │ │ └── default.conf │ ├── package.json │ ├── package.lib.json │ ├── postcss.config.mjs │ ├── public │ │ ├── embed.js │ │ ├── favicon.ico │ │ ├── img │ │ │ ├── F.svg │ │ │ ├── Info.svg │ │ │ ├── W.svg │ │ │ ├── agents │ │ │ │ ├── academicResearchAgentAvatar.png │ │ │ │ ├── businessAnalystAgentAvatar.png │ │ │ │ ├── computerSecurityanalystAvatar.png │ │ │ │ ├── defaultAgentAvatar.JPG │ │ │ │ ├── financeAgentAvatar.png │ │ │ │ ├── mathAgentAvatar.png │ │ │ │ └── travelAgentAvatar.png │ │ │ ├── arrow-circle-up-right.svg │ │ │ ├── arrow-narrow-right.svg │ │ │ ├── browser.svg │ │ │ ├── chat-check.svg │ │ │ ├── chat.svg │ │ │ ├── copy-white.svg │ │ │ ├── copy.svg │ │ │ ├── dinosaur.svg │ │ │ ├── discord.svg │ │ │ ├── docker-blue.svg │ │ │ ├── docker.svg │ │ │ ├── dunk.svg │ │ │ ├── github-blue.svg │ │ │ ├── github-footer.svg │ │ │ ├── github.svg │ │ │ ├── globe.svg │ │ │ ├── gptr-logo.png │ │ │ ├── hiker.svg │ │ │ ├── icon _atom_.svg │ │ │ ├── icon _dumbell_.svg │ │ │ ├── icon _leaf_.svg │ │ │ ├── image.svg │ │ │ ├── indeed.svg │ │ │ ├── link.svg │ │ │ ├── message-question-circle.svg │ │ │ ├── news.svg │ │ │ ├── search.svg │ │ │ ├── share.svg │ │ │ ├── similarTopics.svg │ │ │ ├── sources.svg │ │ │ ├── stock.svg │ │ │ ├── stock2.svg │ │ │ ├── thinking.svg │ │ │ ├── white-books.svg │ │ │ └── x.svg │ │ ├── next.svg │ │ └── vercel.svg │ ├── rollup.config.js │ ├── src │ │ ├── GPTResearcher.tsx │ │ ├── index.css │ │ ├── index.d.ts │ │ ├── index.ts │ │ └── utils │ │ │ └── imageTransformPlugin.js │ ├── styles │ │ └── markdown.css │ ├── tailwind.config.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── types │ │ ├── data.ts │ │ └── react-ga4.d.ts │ └── utils │ │ ├── consolidateBlocks.ts │ │ └── dataProcessing.ts ├── pdf_styles.css ├── scripts.js ├── static │ ├── academicResearchAgentAvatar.png │ ├── businessAnalystAgentAvatar.png │ ├── computerSecurityanalystAvatar.png │ ├── defaultAgentAvatar.JPG │ ├── favicon.ico │ ├── financeAgentAvatar.png │ ├── gptr-logo.png │ ├── mathAgentAvatar.png │ └── travelAgentAvatar.png └── styles.css ├── gpt_researcher ├── README.md ├── __init__.py ├── actions │ ├── __init__.py │ ├── agent_creator.py │ ├── markdown_processing.py │ ├── query_processing.py │ ├── report_generation.py │ ├── retriever.py │ ├── utils.py │ └── web_scraping.py ├── agent.py ├── config │ ├── __init__.py │ ├── config.py │ └── variables │ │ ├── __init__.py │ │ ├── base.py │ │ ├── default.py │ │ └── test_local.json ├── context │ ├── __init__.py │ ├── compression.py │ └── retriever.py ├── document │ ├── __init__.py │ ├── azure_document_loader.py │ ├── document.py │ ├── langchain_document.py │ └── online_document.py ├── llm_provider │ ├── __init__.py │ └── generic │ │ ├── __init__.py │ │ └── base.py ├── memory │ ├── __init__.py │ └── embeddings.py ├── prompts.py ├── retrievers │ ├── __init__.py │ ├── arxiv │ │ ├── __init__.py │ │ └── arxiv.py │ ├── bing │ │ ├── __init__.py │ │ └── bing.py │ ├── custom │ │ ├── __init__.py │ │ └── custom.py │ ├── duckduckgo │ │ ├── __init__.py │ │ └── duckduckgo.py │ ├── exa │ │ ├── __init__.py │ │ └── exa.py │ ├── google │ │ ├── __init__.py │ │ └── google.py │ ├── pubmed_central │ │ ├── __init__.py │ │ └── pubmed_central.py │ ├── searchapi │ │ ├── __init__.py │ │ └── searchapi.py │ ├── searx │ │ ├── __init__.py │ │ └── searx.py │ ├── semantic_scholar │ │ ├── __init__.py │ │ └── semantic_scholar.py │ ├── serpapi │ │ ├── __init__.py │ │ └── serpapi.py │ ├── serper │ │ ├── __init__.py │ │ └── serper.py │ ├── tavily │ │ ├── __init__.py │ │ └── tavily_search.py │ └── utils.py ├── scraper │ ├── __init__.py │ ├── arxiv │ │ ├── __init__.py │ │ └── arxiv.py │ ├── beautiful_soup │ │ ├── __init__.py │ │ └── beautiful_soup.py │ ├── browser │ │ ├── __init__.py │ │ ├── browser.py │ │ ├── js │ │ │ └── overlay.js │ │ ├── nodriver_scraper.py │ │ └── processing │ │ │ ├── __init__.py │ │ │ ├── html.py │ │ │ └── scrape_skills.py │ ├── firecrawl │ │ ├── __init__.py │ │ └── firecrawl.py │ ├── pymupdf │ │ ├── __init__.py │ │ └── pymupdf.py │ ├── scraper.py │ ├── tavily_extract │ │ ├── __init__.py │ │ └── tavily_extract.py │ ├── utils.py │ └── web_base_loader │ │ ├── __init__.py │ │ └── web_base_loader.py ├── skills │ ├── __init__.py │ ├── browser.py │ ├── context_manager.py │ ├── curator.py │ ├── deep_research.py │ ├── researcher.py │ └── writer.py ├── utils │ ├── __init__.py │ ├── costs.py │ ├── enum.py │ ├── llm.py │ ├── logger.py │ ├── logging_config.py │ ├── validators.py │ └── workers.py └── vector_store │ ├── __init__.py │ └── vector_store.py ├── langgraph.json ├── main.py ├── mcp-server └── README.md ├── multi_agents ├── README.md ├── __init__.py ├── agent.py ├── agents │ ├── __init__.py │ ├── editor.py │ ├── human.py │ ├── orchestrator.py │ ├── publisher.py │ ├── researcher.py │ ├── reviewer.py │ ├── reviser.py │ ├── utils │ │ ├── __init__.py │ │ ├── file_formats.py │ │ ├── llms.py │ │ ├── pdf_styles.css │ │ ├── utils.py │ │ └── views.py │ └── writer.py ├── langgraph.json ├── main.py ├── memory │ ├── __init__.py │ ├── draft.py │ └── research.py ├── package.json ├── requirements.txt └── task.json ├── poetry.toml ├── pyproject.toml ├── requirements.txt ├── requirements_minimal.txt ├── setup.py └── tests ├── __init__.py ├── docs └── doc.pdf ├── documents-report-source.py ├── gptr-logs-handler.py ├── report-types.py ├── research_test.py ├── test-loaders.py ├── test-openai-llm.py ├── test-your-embeddings.py ├── test-your-llm.py ├── test-your-retriever.py ├── test_logging.py ├── test_logging_output.py ├── test_logs.py ├── test_researcher_logging.py └── vector-store.py /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | output/ 3 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | TAVILY_API_KEY= 3 | DOC_PATH=./my-docs 4 | 5 | # NEXT_PUBLIC_GPTR_API_URL=http://0.0.0.0:8000 # Defaults to localhost:8000 if not set -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "pip" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | - package-ecosystem: "docker" 13 | directory: "/" 14 | schedule: 15 | interval: "weekly" 16 | -------------------------------------------------------------------------------- /.github/workflows/docker-build.yml: -------------------------------------------------------------------------------- 1 | name: GPTR tests 2 | run-name: ${{ github.actor }} ran the GPTR tests flow 3 | permissions: 4 | contents: read 5 | pull-requests: write 6 | on: 7 | workflow_dispatch: # Add this line to enable manual triggering 8 | # pull_request: 9 | # types: [opened, synchronize] 10 | 11 | jobs: 12 | docker: 13 | runs-on: ubuntu-latest 14 | environment: tests # Specify the environment to use for this job 15 | env: 16 | # Ensure these environment variables are set for the entire job 17 | OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} 18 | TAVILY_API_KEY: ${{ secrets.TAVILY_API_KEY }} 19 | LANGCHAIN_API_KEY: ${{ secrets.LANGCHAIN_API_KEY }} 20 | steps: 21 | - name: Git checkout 22 | uses: actions/checkout@v3 23 | 24 | - name: Set up QEMU 25 | uses: docker/setup-qemu-action@v2 26 | 27 | - name: Set up Docker Buildx 28 | uses: docker/setup-buildx-action@v2 29 | with: 30 | driver: docker 31 | 32 | # - name: Build Docker images 33 | # uses: docker/build-push-action@v4 34 | # with: 35 | # push: false 36 | # tags: gptresearcher/gpt-researcher:latest 37 | # file: Dockerfile 38 | 39 | - name: Set up Docker Compose 40 | run: | 41 | sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 42 | sudo chmod +x /usr/local/bin/docker-compose 43 | - name: Run tests with Docker Compose 44 | run: | 45 | docker-compose --profile test run --rm gpt-researcher-tests -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Ignore env containing secrets 2 | .env 3 | .venv 4 | .envrc 5 | 6 | #Ignore Virtual Env 7 | env/ 8 | venv/ 9 | .venv/ 10 | 11 | # Other Environments 12 | ENV/ 13 | env.bak/ 14 | venv.bak/ 15 | 16 | #Ignore generated outputs 17 | outputs/ 18 | *.lock 19 | dist/ 20 | gpt_researcher.egg-info/ 21 | 22 | #Ignore my local docs 23 | my-docs/ 24 | 25 | #Ignore pycache 26 | **/__pycache__/ 27 | 28 | #Ignore mypy cache 29 | .mypy_cache/ 30 | node_modules 31 | .idea 32 | .DS_Store 33 | .docusaurus 34 | build 35 | docs/build 36 | 37 | .vscode/launch.json 38 | .langgraph-data/ 39 | .next/ 40 | package-lock.json 41 | 42 | #Vim swp files 43 | *.swp 44 | 45 | # Log files 46 | logs/ 47 | *.orig 48 | *.log 49 | server_log.txt 50 | 51 | #Cursor Rules 52 | .cursorrules 53 | CURSOR_RULES.md 54 | /.history 55 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.11 2 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: python -m uvicorn backend.server.server:app --host=0.0.0.0 --port=${PORT} -------------------------------------------------------------------------------- /backend/__init__.py: -------------------------------------------------------------------------------- 1 | from multi_agents import agents -------------------------------------------------------------------------------- /backend/chat/__init__.py: -------------------------------------------------------------------------------- 1 | from .chat import ChatAgentWithMemory -------------------------------------------------------------------------------- /backend/memory/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/backend/memory/__init__.py -------------------------------------------------------------------------------- /backend/memory/draft.py: -------------------------------------------------------------------------------- 1 | from typing import TypedDict, List, Annotated 2 | import operator 3 | 4 | 5 | class DraftState(TypedDict): 6 | task: dict 7 | topic: str 8 | draft: dict 9 | review: str 10 | revision_notes: str -------------------------------------------------------------------------------- /backend/memory/research.py: -------------------------------------------------------------------------------- 1 | from typing import TypedDict, List, Annotated 2 | import operator 3 | 4 | 5 | class ResearchState(TypedDict): 6 | task: dict 7 | initial_research: str 8 | sections: List[str] 9 | research_data: List[dict] 10 | # Report layout 11 | title: str 12 | headers: dict 13 | date: str 14 | table_of_contents: str 15 | introduction: str 16 | conclusion: str 17 | sources: List[str] 18 | report: str 19 | 20 | 21 | -------------------------------------------------------------------------------- /backend/report_type/__init__.py: -------------------------------------------------------------------------------- 1 | from .basic_report.basic_report import BasicReport 2 | from .detailed_report.detailed_report import DetailedReport 3 | 4 | __all__ = [ 5 | "BasicReport", 6 | "DetailedReport" 7 | ] -------------------------------------------------------------------------------- /backend/report_type/basic_report/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/backend/report_type/basic_report/__init__.py -------------------------------------------------------------------------------- /backend/report_type/basic_report/basic_report.py: -------------------------------------------------------------------------------- 1 | from fastapi import WebSocket 2 | from typing import Any 3 | 4 | from gpt_researcher import GPTResearcher 5 | 6 | 7 | class BasicReport: 8 | def __init__( 9 | self, 10 | query: str, 11 | query_domains: list, 12 | report_type: str, 13 | report_source: str, 14 | source_urls, 15 | document_urls, 16 | tone: Any, 17 | config_path: str, 18 | websocket: WebSocket, 19 | headers=None 20 | ): 21 | self.query = query 22 | self.query_domains = query_domains 23 | self.report_type = report_type 24 | self.report_source = report_source 25 | self.source_urls = source_urls 26 | self.document_urls = document_urls 27 | self.tone = tone 28 | self.config_path = config_path 29 | self.websocket = websocket 30 | self.headers = headers or {} 31 | 32 | # Initialize researcher 33 | self.gpt_researcher = GPTResearcher( 34 | query=self.query, 35 | query_domains=self.query_domains, 36 | report_type=self.report_type, 37 | report_source=self.report_source, 38 | source_urls=self.source_urls, 39 | document_urls=self.document_urls, 40 | tone=self.tone, 41 | config_path=self.config_path, 42 | websocket=self.websocket, 43 | headers=self.headers 44 | ) 45 | 46 | async def run(self): 47 | await self.gpt_researcher.conduct_research() 48 | report = await self.gpt_researcher.write_report() 49 | return report 50 | -------------------------------------------------------------------------------- /backend/report_type/deep_research/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/backend/report_type/deep_research/__init__.py -------------------------------------------------------------------------------- /backend/report_type/deep_research/main.py: -------------------------------------------------------------------------------- 1 | from gpt_researcher import GPTResearcher 2 | from backend.utils import write_md_to_pdf 3 | import asyncio 4 | 5 | 6 | async def main(task: str): 7 | # Progress callback 8 | def on_progress(progress): 9 | print(f"Depth: {progress.current_depth}/{progress.total_depth}") 10 | print(f"Breadth: {progress.current_breadth}/{progress.total_breadth}") 11 | print(f"Queries: {progress.completed_queries}/{progress.total_queries}") 12 | if progress.current_query: 13 | print(f"Current query: {progress.current_query}") 14 | 15 | # Initialize researcher with deep research type 16 | researcher = GPTResearcher( 17 | query=task, 18 | report_type="deep", # This will trigger deep research 19 | ) 20 | 21 | # Run research with progress tracking 22 | print("Starting deep research...") 23 | context = await researcher.conduct_research(on_progress=on_progress) 24 | print("\nResearch completed. Generating report...") 25 | 26 | # Generate the final report 27 | report = await researcher.write_report() 28 | await write_md_to_pdf(report, "deep_research_report") 29 | print(f"\nFinal Report: {report}") 30 | 31 | if __name__ == "__main__": 32 | query = "What are the most effective ways for beginners to start investing?" 33 | asyncio.run(main(query)) -------------------------------------------------------------------------------- /backend/report_type/detailed_report/README.md: -------------------------------------------------------------------------------- 1 | ## Detailed Reports 2 | 3 | Introducing long and detailed reports, with a completely new architecture inspired by the latest [STORM](https://arxiv.org/abs/2402.14207) paper. 4 | 5 | In this method we do the following: 6 | 7 | 1. Trigger Initial GPT Researcher report based on task 8 | 2. Generate subtopics from research summary 9 | 3. For each subtopic the headers of the subtopic report are extracted and accumulated 10 | 4. For each subtopic a report is generated making sure that any information about the headers accumulated until now are not re-generated. 11 | 5. An additional introduction section is written along with a table of contents constructed from the entire report. 12 | 6. The final report is constructed by appending these : Intro + Table of contents + Subsection reports -------------------------------------------------------------------------------- /backend/report_type/detailed_report/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/backend/report_type/detailed_report/__init__.py -------------------------------------------------------------------------------- /backend/server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/backend/server/__init__.py -------------------------------------------------------------------------------- /backend/server/app.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI, WebSocket 2 | from fastapi.middleware.cors import CORSMiddleware 3 | import logging 4 | from backend.chat.chat import ChatAgentWithMemory 5 | 6 | logger = logging.getLogger(__name__) 7 | 8 | app = FastAPI() 9 | 10 | # Add CORS middleware 11 | app.add_middleware( 12 | CORSMiddleware, 13 | allow_origins=["*"], # In production, replace with your frontend domain 14 | allow_credentials=True, 15 | allow_methods=["*"], 16 | allow_headers=["*"], 17 | ) 18 | 19 | @app.get("/") 20 | async def read_root(): 21 | return {"message": "Welcome to GPT Researcher"} 22 | 23 | @app.websocket("/ws") 24 | async def websocket_endpoint(websocket: WebSocket): 25 | await websocket.accept() 26 | chat_agent = ChatAgentWithMemory(report="Sample report", config_path="path/to/config", headers={}) 27 | try: 28 | while True: 29 | data = await websocket.receive_text() 30 | await chat_agent.chat(data, websocket) 31 | except WebSocketDisconnect: 32 | await websocket.close() 33 | -------------------------------------------------------------------------------- /citation.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.0.0 2 | message: "If you use this software, please cite it as below." 3 | authors: 4 | - family-names: Elovic 5 | given-names: Assaf 6 | title: gpt-researcher 7 | version: 0.5.4 8 | date-released: 2023-07-23 9 | repository-code: https://github.com/assafelovic/gpt-researcher 10 | url: https://gptr.dev -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | gpt-researcher: 3 | pull_policy: build 4 | image: gptresearcher/gpt-researcher 5 | build: ./ 6 | environment: 7 | OPENAI_API_KEY: ${OPENAI_API_KEY} 8 | TAVILY_API_KEY: ${TAVILY_API_KEY} 9 | LANGCHAIN_API_KEY: ${LANGCHAIN_API_KEY} 10 | LOGGING_LEVEL: INFO 11 | volumes: 12 | - ${PWD}/my-docs:/usr/src/app/my-docs:rw 13 | - ${PWD}/outputs:/usr/src/app/outputs:rw 14 | - ${PWD}/logs:/usr/src/app/logs:rw 15 | user: root 16 | restart: always 17 | ports: 18 | - 8000:8000 19 | 20 | gptr-nextjs: 21 | pull_policy: build 22 | image: gptresearcher/gptr-nextjs 23 | stdin_open: true 24 | environment: 25 | CHOKIDAR_USEPOLLING: "true" 26 | LOGGING_LEVEL: INFO 27 | NEXT_PUBLIC_GA_MEASUREMENT_ID: ${NEXT_PUBLIC_GA_MEASUREMENT_ID} 28 | NEXT_PUBLIC_GPTR_API_URL: ${NEXT_PUBLIC_GPTR_API_URL} 29 | build: 30 | dockerfile: Dockerfile.dev 31 | context: frontend/nextjs 32 | volumes: 33 | - /app/node_modules 34 | - ./frontend/nextjs:/app 35 | - ./frontend/nextjs/.next:/app/.next 36 | - ./outputs:/app/outputs 37 | restart: always 38 | ports: 39 | - 3000:3000 40 | 41 | gpt-researcher-tests: 42 | image: gptresearcher/gpt-researcher-tests 43 | build: ./ 44 | environment: 45 | OPENAI_API_KEY: ${OPENAI_API_KEY} 46 | TAVILY_API_KEY: ${TAVILY_API_KEY} 47 | LANGCHAIN_API_KEY: ${LANGCHAIN_API_KEY} 48 | LOGGING_LEVEL: INFO 49 | profiles: ["test"] 50 | command: > 51 | /bin/sh -c " 52 | pip install pytest pytest-asyncio faiss-cpu && 53 | python -m pytest tests/report-types.py && 54 | python -m pytest tests/vector-store.py 55 | " 56 | 57 | discord-bot: 58 | build: 59 | context: ./docs/discord-bot 60 | dockerfile: Dockerfile.dev 61 | environment: 62 | - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN} 63 | - DISCORD_CLIENT_ID=${DISCORD_CLIENT_ID} 64 | volumes: 65 | - ./docs/discord-bot:/app 66 | - /app/node_modules 67 | ports: 68 | - 3001:3000 69 | profiles: ["discord"] 70 | restart: always 71 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | docs.gptr.dev -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ## Prerequisites 6 | 7 | To build and test documentation locally, begin by downloading and installing [Node.js](https://nodejs.org/en/download/), and then installing [Yarn](https://classic.yarnpkg.com/en/). 8 | On Windows, you can install via the npm package manager (npm) which comes bundled with Node.js: 9 | 10 | ```console 11 | npm install --global yarn 12 | ``` 13 | 14 | ## Installation 15 | 16 | ```console 17 | pip install pydoc-markdown 18 | cd website 19 | yarn install 20 | ``` 21 | 22 | ## Local Development 23 | 24 | Navigate to the website folder and run: 25 | 26 | ```console 27 | pydoc-markdown 28 | yarn start 29 | ``` 30 | 31 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 32 | -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/blog/2023-09-22-gpt-researcher/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/blog/2023-09-22-gpt-researcher/architecture.png -------------------------------------------------------------------------------- /docs/blog/2023-09-22-gpt-researcher/planner.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/blog/2023-09-22-gpt-researcher/planner.jpeg -------------------------------------------------------------------------------- /docs/blog/2023-11-12-openai-assistant/diagram-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/blog/2023-11-12-openai-assistant/diagram-1.png -------------------------------------------------------------------------------- /docs/blog/2023-11-12-openai-assistant/diagram-assistant.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/blog/2023-11-12-openai-assistant/diagram-assistant.jpeg -------------------------------------------------------------------------------- /docs/blog/2024-05-19-gptr-langgraph/architecture.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/blog/2024-05-19-gptr-langgraph/architecture.jpeg -------------------------------------------------------------------------------- /docs/blog/2024-05-19-gptr-langgraph/blog-langgraph.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/blog/2024-05-19-gptr-langgraph/blog-langgraph.jpeg -------------------------------------------------------------------------------- /docs/blog/2024-09-7-hybrid-research/gptr-hybrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/blog/2024-09-7-hybrid-research/gptr-hybrid.png -------------------------------------------------------------------------------- /docs/blog/authors.yml: -------------------------------------------------------------------------------- 1 | assafe: 2 | name: Assaf Elovic 3 | title: Creator @ GPT Researcher and Tavily 4 | url: https://github.com/assafelovic 5 | image_url: https://lh3.googleusercontent.com/a/ACg8ocJtrLku69VG_2Y0sJa5mt66gIGNaEBX5r_mgE6CRPEb7A=s96-c 6 | 7 | elishakay: 8 | name: Elisha Kramer 9 | title: Core Contributor @ GPT Researcher 10 | url: https://github.com/ElishaKay 11 | image_url: https://avatars.githubusercontent.com/u/16700452 12 | -------------------------------------------------------------------------------- /docs/discord-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18.17.0-alpine 2 | WORKDIR /app 3 | COPY ./package.json ./ 4 | RUN npm install --legacy-peer-deps 5 | COPY . . 6 | CMD ["node", "index.js"] -------------------------------------------------------------------------------- /docs/discord-bot/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM node:18.17.0-alpine 2 | WORKDIR /app 3 | COPY ./package.json ./ 4 | RUN npm install --legacy-peer-deps 5 | RUN npm install -g nodemon 6 | COPY . . 7 | CMD ["nodemon", "index.js"] -------------------------------------------------------------------------------- /docs/discord-bot/commands/ask.js: -------------------------------------------------------------------------------- 1 | const { SlashCommandBuilder } = require('discord.js'); 2 | 3 | module.exports = { 4 | data: new SlashCommandBuilder() 5 | .setName('ask') 6 | .setDescription('Ask a question to the bot'), 7 | async execute(interaction) { 8 | await interaction.reply('Please provide your question.'); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /docs/discord-bot/deploy-commands.js: -------------------------------------------------------------------------------- 1 | const { Client, GatewayIntentBits, REST, Routes } = require('discord.js'); 2 | require('dotenv').config(); 3 | 4 | // Create a new REST client and set your bot token 5 | const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_BOT_TOKEN); 6 | 7 | // Define commands 8 | const commands = [ 9 | { 10 | name: 'ping', 11 | description: 'Replies with Pong!', 12 | }, 13 | { 14 | name: 'ask', 15 | description: 'Ask a question to the bot', 16 | }, 17 | ]; 18 | 19 | // Deploy commands to Discord 20 | (async () => { 21 | try { 22 | console.log('Started refreshing application (/) commands.'); 23 | 24 | await rest.put(Routes.applicationCommands(process.env.DISCORD_CLIENT_ID), { 25 | body: commands, 26 | }); 27 | 28 | console.log('Successfully reloaded application (/) commands.'); 29 | } catch (error) { 30 | console.error(error); 31 | } 32 | })(); 33 | -------------------------------------------------------------------------------- /docs/discord-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Discord-Bot-JS", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "discord.js": "^14.16.1", 8 | "dotenv": "^16.4.5", 9 | "express": "^4.17.1", 10 | "jsonrepair": "^3.8.0", 11 | "nodemon": "^3.1.4", 12 | "ws": "^8.18.0" 13 | }, 14 | "scripts": { 15 | "test": "echo \"Error: no test specified\" && exit 1", 16 | "dev": "nodemon --legacy-watch index.js" 17 | }, 18 | "keywords": [], 19 | "author": "", 20 | "license": "ISC" 21 | } 22 | -------------------------------------------------------------------------------- /docs/discord-bot/server.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | 3 | const server = express() 4 | 5 | server.all("/", (req, res) => { 6 | res.send("Bot is running!") 7 | }) 8 | 9 | function keepAlive() { 10 | server.listen(5000, () => { 11 | console.log("Server is ready.") 12 | }) 13 | 14 | // Handle uncaught exceptions 15 | process.on("uncaughtException", (err) => { 16 | console.error("Uncaught Exception:", err); 17 | // Graceful shutdown logic 18 | // process.exit(1); // Exit process to trigger Docker's restart policy 19 | }); 20 | 21 | // Handle unhandled promise rejections 22 | process.on("unhandledRejection", (reason, promise) => { 23 | console.error("Unhandled Rejection at:", promise, "reason:", reason); 24 | // Graceful shutdown logic 25 | // process.exit(1); // Exit process to trigger Docker's restart policy 26 | }); 27 | } 28 | 29 | module.exports = keepAlive -------------------------------------------------------------------------------- /docs/docs/contribute.md: -------------------------------------------------------------------------------- 1 | # Contribute 2 | 3 | We highly welcome contributions! Please check out [contributing](https://github.com/assafelovic/gpt-researcher/blob/master/CONTRIBUTING.md) if you're interested. 4 | 5 | Please check out our [roadmap](https://trello.com/b/3O7KBePw/gpt-researcher-roadmap) page and reach out to us via our [Discord community](https://discord.gg/QgZXvJAccX) if you're interested in joining our mission. -------------------------------------------------------------------------------- /docs/docs/examples/sample_report.py: -------------------------------------------------------------------------------- 1 | import nest_asyncio # required for notebooks 2 | 3 | nest_asyncio.apply() 4 | 5 | from gpt_researcher import GPTResearcher 6 | import asyncio 7 | 8 | 9 | async def get_report(query: str, report_type: str, custom_prompt: str = None): 10 | researcher = GPTResearcher(query, report_type) 11 | research_result = await researcher.conduct_research() 12 | 13 | # Generate report with optional custom prompt 14 | report = await researcher.write_report(custom_prompt=custom_prompt) 15 | 16 | # Get additional information 17 | research_context = researcher.get_research_context() 18 | research_costs = researcher.get_costs() 19 | research_images = researcher.get_research_images() 20 | research_sources = researcher.get_research_sources() 21 | 22 | return report, research_context, research_costs, research_images, research_sources 23 | 24 | 25 | if __name__ == "__main__": 26 | query = "Should I invest in Nvidia?" 27 | report_type = "research_report" 28 | 29 | # Standard report 30 | report, context, costs, images, sources = asyncio.run(get_report(query, report_type)) 31 | 32 | print("Standard Report:") 33 | print(report) 34 | 35 | # Custom report with specific formatting requirements 36 | custom_prompt = "Answer in short, 2 paragraphs max without citations. Focus on the most important facts for investors." 37 | custom_report, _, _, _, _ = asyncio.run(get_report(query, report_type, custom_prompt)) 38 | 39 | print("\nCustomized Short Report:") 40 | print(custom_report) 41 | 42 | print("\nResearch Costs:") 43 | print(costs) 44 | print("\nNumber of Research Images:") 45 | print(len(images)) 46 | print("\nNumber of Research Sources:") 47 | print(len(sources)) -------------------------------------------------------------------------------- /docs/docs/examples/sample_sources_only.py: -------------------------------------------------------------------------------- 1 | from gpt_researcher import GPTResearcher 2 | import asyncio 3 | 4 | 5 | async def get_report(query: str, report_source: str, sources: list) -> str: 6 | researcher = GPTResearcher(query=query, report_source=report_source, source_urls=sources) 7 | research_context = await researcher.conduct_research() 8 | return await researcher.write_report() 9 | 10 | if __name__ == "__main__": 11 | query = "What are the biggest trends in AI lately?" 12 | report_source = "static" 13 | sources = [ 14 | "https://en.wikipedia.org/wiki/Artificial_intelligence", 15 | "https://www.ibm.com/think/insights/artificial-intelligence-trends", 16 | "https://www.forbes.com/advisor/business/ai-statistics" 17 | ] 18 | 19 | report = asyncio.run(get_report(query=query, report_source=report_source, sources=sources)) 20 | print(report) 21 | -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/context/azure-storage.md: -------------------------------------------------------------------------------- 1 | # Azure Storage 2 | 3 | If you want to use Azure Blob Storage as the source for your GPT Researcher report context, follow these steps: 4 | 5 | > **Step 1** - Set these environment variables with a .env file in the root folder 6 | 7 | ```bash 8 | AZURE_CONNECTION_STRING= 9 | AZURE_CONTAINER_NAME= 10 | ``` 11 | 12 | > **Step 2** - Add the `azure-storage-blob` dependency to your requirements.txt file 13 | 14 | ```bash 15 | azure-storage-blob 16 | ``` 17 | 18 | > **Step 3** - When running the GPTResearcher class, pass the `report_source` as `azure` 19 | 20 | ```python 21 | report = GPTResearcher( 22 | query="What happened in the latest burning man floods?", 23 | report_type="research_report", 24 | report_source="azure", 25 | ) 26 | ``` -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/context/img/gptr-hybrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/docs/gpt-researcher/context/img/gptr-hybrid.png -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/context/img/nextjs-filter-by-domain.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/docs/gpt-researcher/context/img/nextjs-filter-by-domain.JPG -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/context/img/vanilla-filter-by-domains.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/docs/gpt-researcher/context/img/vanilla-filter-by-domains.png -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/context/local-docs.md: -------------------------------------------------------------------------------- 1 | # Local Documents 2 | 3 | ## Just Local Docs 4 | 5 | You can instruct the GPT Researcher to run research tasks based on your local documents. Currently supported file formats are: PDF, plain text, CSV, Excel, Markdown, PowerPoint, and Word documents. 6 | 7 | Step 1: Add the env variable `DOC_PATH` pointing to the folder where your documents are located. 8 | 9 | ```bash 10 | export DOC_PATH="./my-docs" 11 | ``` 12 | 13 | Step 2: 14 | - If you're running the frontend app on localhost:8000, simply select "My Documents" from the "Report Source" Dropdown Options. 15 | - If you're running GPT Researcher with the [PIP package](https://docs.tavily.com/docs/gpt-researcher/gptr/pip-package), pass the `report_source` argument as "local" when you instantiate the `GPTResearcher` class [code sample here](https://docs.gptr.dev/docs/gpt-researcher/context/tailored-research). 16 | 17 | ## Local Docs + Web (Hybrid) 18 | 19 | ![GPT Researcher hybrid research](./img/gptr-hybrid.png) 20 | 21 | Check out the blog post on [Hybrid Research](https://docs.gptr.dev/blog/gptr-hybrid) to learn more about how to combine local documents with web research. 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/frontend/discord-bot.md: -------------------------------------------------------------------------------- 1 | # Discord Bot 2 | 3 | ## Intro 4 | 5 | You can either leverage the official GPTR Discord bot or create your own custom bot. 6 | 7 | To add the official GPTR Discord bot, simply [click here to invite GPTR to your Discord server](https://discord.com/oauth2/authorize?client_id=1281438963034361856&permissions=1689934339898432&integration_type=0&scope=bot). 8 | 9 | 10 | ## To create your own discord bot with GPTR functionality 11 | 12 | Add a .env file in the root of the project and add the following: 13 | 14 | ``` 15 | DISCORD_BOT_TOKEN= 16 | DISCORD_CLIENT_ID= 17 | ``` 18 | You can fetch the token from the Discord Developer Portal by following these steps: 19 | 20 | 1. Go to https://discord.com/developers/applications/ 21 | 2. Click the "New Application" button and give your bot a name 22 | 3. Navigate to the OAuth2 tab to generate an invite URL for your bot 23 | 4. Under "Scopes", select "bot" 24 | 25 | ![OAuth2 URL Generator](./img/oath2-url-generator.png) 26 | 27 | 5. Select the appropriate bot permissions 28 | 29 | ![Bot Permissions](./img/bot-permissions.png) 30 | 31 | 6. Copy your bot's token and paste it into the `.env` file you created earlier 32 | 33 | 34 | ### Deploying the bot commands 35 | 36 | ```bash 37 | node deploy-commands.js 38 | ``` 39 | 40 | In our case, this will make the "ask" and "ping" commands available to users of the bot. 41 | 42 | 43 | ### Running the bot via Docker 44 | 45 | ```bash 46 | docker compose --profile discord run --rm discord-bot 47 | ``` 48 | 49 | ### Running the bot via CLI 50 | 51 | ```bash 52 | # install dependencies 53 | npm install 54 | 55 | # run the bot 56 | npm run dev 57 | ``` 58 | 59 | ### Installing NodeJS and NPM on Ubuntu 60 | 61 | ```bash 62 | #install nvm 63 | wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash 64 | 65 | export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" 66 | [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm 67 | 68 | # install nodejs 69 | nvm install 18.17.0 70 | 71 | # install npm 72 | sudo apt-get install npm 73 | ``` 74 | -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/frontend/embed-script.md: -------------------------------------------------------------------------------- 1 | # Embed Script 2 | 3 | The embed script enables you to embed the latest GPTR NextJS app into your web app. 4 | 5 | To achieve this, simply add these 2 script tags into your HTML: 6 | 7 | ```javascript 8 | 9 | 10 | ``` 11 | 12 | Here's a minmalistic HTML example (P.S. You can also save this as an index.html file and open it with your Web Browser) 13 | 14 | ```html 15 | 16 | 17 | 18 | 19 | 20 | GPT Researcher Embed Demo 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ``` 29 | 30 | This example relies on setting a custom localstorage value for `GPTR_API_URL`. To point your embedded frontend at a custom GPTR API Server, feel free to edit `http://localhost:8000` to your custom GPTR server address. -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/frontend/img/bot-permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/docs/gpt-researcher/frontend/img/bot-permissions.png -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/frontend/img/oath2-url-generator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/docs/gpt-researcher/frontend/img/oath2-url-generator.png -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/frontend/introduction.md: -------------------------------------------------------------------------------- 1 | # Intro to the Frontends 2 | 3 | The frontends enhance GPT-Researcher by providing: 4 | 5 | 1. Intuitive Research Interface: Streamlined input for research queries. 6 | 2. Real-time Progress Tracking: Visual feedback on ongoing research tasks. 7 | 3. Interactive Results Display: Easy-to-navigate presentation of findings. 8 | 4. Customizable Settings: Adjust research parameters to suit specific needs. 9 | 5. Responsive Design: Optimal experience across various devices. 10 | 11 | These features aim to make the research process more efficient and user-friendly, complementing GPT-Researcher's powerful agent capabilities. 12 | 13 | ## Choosing an Option 14 | 15 | - Static Frontend: Quick setup, lightweight deployment. 16 | - NextJS Frontend: Feature-rich, scalable, better performance and SEO (For production, NextJS is recommended) 17 | - Discord Bot: Integrate GPT-Researcher into your Discord server. -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/frontend/react-package.md: -------------------------------------------------------------------------------- 1 | # React Package 2 | 3 | The GPTR React package is an abstraction on top of the NextJS app meant to empower users to easily import the GPTR frontend into any React App. The package is [available on npm](https://www.npmjs.com/package/gpt-researcher-ui). 4 | 5 | 6 | ## Installation 7 | 8 | ```bash 9 | npm install gpt-researcher-ui 10 | ``` 11 | 12 | ## Usage 13 | 14 | ```javascript 15 | import React from 'react'; 16 | import { GPTResearcher } from 'gpt-researcher-ui'; 17 | 18 | function App() { 19 | return ( 20 |
21 | console.log('Research results:', results)} 25 | /> 26 |
27 | ); 28 | } 29 | 30 | export default App; 31 | ``` 32 | 33 | 34 | ## Publishing to a private npm registry 35 | 36 | If you'd like to build and publish the package into your own private npm registry, you can do so by running the following commands: 37 | 38 | ```bash 39 | cd frontend/nextjs/ 40 | npm run build:lib 41 | npm run build:types 42 | npm publish 43 | ``` 44 | 45 | -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/frontend/vanilla-js-frontend.md: -------------------------------------------------------------------------------- 1 | # Vanilla JS Frontend 2 | 3 | The VanillaJS frontend is a lightweight solution leveraging FastAPI to serve static files. 4 | 5 | ### Demo 6 | 7 | 8 | #### Prerequisites 9 | - Python 3.11+ 10 | - pip 11 | 12 | #### Setup and Running 13 | 14 | 1. Install required packages: 15 | ``` 16 | pip install -r requirements.txt 17 | ``` 18 | 19 | 2. Start the server: 20 | ``` 21 | python -m uvicorn main:app 22 | ``` 23 | 24 | 3. Access at `http://localhost:8000` 25 | -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/frontend/visualizing-websockets.md: -------------------------------------------------------------------------------- 1 | # Visualizing Websockets 2 | 3 | The GPTR Frontend is powered by Websockets streaming back from the Backend. This allows for real-time updates on the status of your research tasks, as well as the ability to interact with the Backend directly from the Frontend. 4 | 5 | 6 | ## Inspecting Websockets 7 | 8 | When running reports via the frontend, you can inspect the websocket messages in the Network Tab. 9 | 10 | Here's how: 11 | 12 | ![image](https://github.com/user-attachments/assets/15fcb5a4-77ea-4b3b-87d7-55d4b6f80095) 13 | 14 | 15 | ## Am I polling the right URL? 16 | 17 | If you're concerned that your frontend isn't hitting the right API Endpoint, you can check the URL in the Network Tab. 18 | 19 | Click into the WS request & go to the "Headers" tab 20 | 21 | ![image](https://github.com/user-attachments/assets/dbd58c1d-3506-411a-852b-e1b133b6f5c8) 22 | 23 | For debugging, have a look at the getHost function. -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/getting-started/getting-started-with-docker.md: -------------------------------------------------------------------------------- 1 | # Docker: Quickstart 2 | 3 | > **Step 1** - Install & Open Docker Desktop 4 | 5 | Follow instructions at https://www.docker.com/products/docker-desktop/ 6 | 7 | 8 | > **Step 2** - [Follow this flow](https://www.youtube.com/watch?v=x1gKFt_6Us4) 9 | 10 | This mainly includes cloning the '.env.example' file, adding your API Keys to the cloned file and saving the file as '.env' 11 | 12 | In `requirements.txt` add the relevant langchain packages for the LLM your choose (langchain-google-genai, langchain-deepseek, langchain_mistralai for example) 13 | 14 | > **Step 3** - Within root, run with Docker. 15 | 16 | ```bash 17 | docker-compose up --build 18 | ``` 19 | 20 | If that doesn't work, try running it without the dash: 21 | ```bash 22 | docker compose up --build 23 | ``` 24 | 25 | > **Step 4** - By default, if you haven't uncommented anything in your docker-compose file, this flow will start 2 processes: 26 | - the Python server running on localhost:8000 27 | - the React app running on localhost:3000 28 | 29 | Visit localhost:3000 on any browser and enjoy researching! 30 | 31 | 32 | ## Running with the Docker CLI 33 | 34 | If you want to run the Docker container without using docker-compose, you can use the following command: 35 | 36 | ```bash 37 | docker run -it --name gpt-researcher -p 8000:8000 --env-file .env -v /absolute/path/to/gptr_docs:/my-docs gpt-researcher 38 | ``` 39 | 40 | This will run the Docker container and mount the `/gptr_docs` directory to the container's `/my-docs` directory for analysis by the GPTR API Server. 41 | -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/gptr/automated-tests.md: -------------------------------------------------------------------------------- 1 | # Automated Tests 2 | 3 | ## Automated Testing with Github Actions 4 | 5 | This repository contains the code for the automated testing of the GPT-Researcher Repo using Github Actions. 6 | 7 | The tests are triggered in a docker container which runs the tests via the `pytest` module. 8 | 9 | ## Running the Tests 10 | 11 | You can run the tests: 12 | 13 | ### Via a docker command 14 | 15 | ```bash 16 | docker-compose --profile test run --rm gpt-researcher-tests 17 | ``` 18 | 19 | ### Via a Github Action 20 | 21 | ![image](https://github.com/user-attachments/assets/721fca20-01bb-4c10-9cf9-19d823bebbb0) 22 | 23 | Attaching here the required settings & screenshots on the github repo level: 24 | 25 | Step 1: Within the repo, press the "Settings" tab 26 | 27 | Step 2: Create a new environment named "tests" (all lowercase) 28 | 29 | Step 3: Click into the "tests" environment & add environment secrets of ```OPENAI_API_KEY``` & ```TAVILY_API_KEY``` 30 | 31 | Get the keys from here: 32 | 33 | https://app.tavily.com/sign-in 34 | 35 | https://platform.openai.com/api-keys 36 | 37 | 38 | ![Screen Shot 2024-07-28 at 9 00 19](https://github.com/user-attachments/assets/7cd341c6-d8d4-461f-ab5e-325abc9fe509) 39 | ![Screen Shot 2024-07-28 at 9 02 55](https://github.com/user-attachments/assets/a3744f01-06a6-4c9d-8aa0-1fc742d3e866) 40 | 41 | If configured correctly, here's what the Github action should look like when opening a new PR or committing to an open PR: 42 | 43 | ![Screen Shot 2024-07-28 at 8 57 02](https://github.com/user-attachments/assets/30dbc668-4e6a-4b3b-a02e-dc859fc9bd3d) -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/gptr/example.md: -------------------------------------------------------------------------------- 1 | # Agent Example 2 | 3 | If you're interested in using GPT Researcher as a standalone agent, you can easily import it into any existing Python project. Below, is an example of calling the agent to generate a research report: 4 | 5 | ```python 6 | from gpt_researcher import GPTResearcher 7 | import asyncio 8 | 9 | async def fetch_report(query): 10 | """ 11 | Fetch a research report based on the provided query and report type. 12 | """ 13 | researcher = GPTResearcher(query=query) 14 | await researcher.conduct_research() 15 | report = await researcher.write_report() 16 | return report 17 | 18 | async def generate_research_report(query): 19 | """ 20 | This is a sample script that executes an async main function to run a research report. 21 | """ 22 | report = await fetch_report(query) 23 | print(report) 24 | 25 | if __name__ == "__main__": 26 | QUERY = "What happened in the latest burning man floods?" 27 | asyncio.run(generate_research_report(query=QUERY)) 28 | ``` 29 | 30 | You can further enhance this example to use the returned report as context for generating valuable content such as news article, marketing content, email templates, newsletters, etc. 31 | 32 | You can also use GPT Researcher to gather information about code documentation, business analysis, financial information and more. All of which can be used to complete much more complex tasks that require factual and high quality realtime information. 33 | -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/gptr/npm-package.md: -------------------------------------------------------------------------------- 1 | # npm package 2 | 3 | The [gpt-researcher npm package](https://www.npmjs.com/package/gpt-researcher) is a WebSocket client for interacting with GPT Researcher. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | npm install gpt-researcher 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```javascript 14 | const GPTResearcher = require('gpt-researcher'); 15 | 16 | const researcher = new GPTResearcher({ 17 | host: 'localhost:8000', 18 | logListener: (data) => console.log('logListener logging data: ',data) 19 | }); 20 | 21 | researcher.sendMessage({ 22 | query: 'Does providing better context reduce LLM hallucinations?', 23 | moreContext: 'Provide a detailed answer' 24 | }); 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/handling-logs/langsmith-logs.md: -------------------------------------------------------------------------------- 1 | # Langsmith Logs 2 | 3 | With the help of Langsmith, you can easily visualize logs on cost and errors within your Langsmith Dashboard (calculated per LLM call or grouped by project) 4 | 5 | Here are the steps to setup Langsmith: 6 | 7 | Step 1: Setup a Langsmith account at: [smith.langchain.com](https://smith.langchain.com) 8 | 9 | Step 2: Create a new API key at: [smith.langchain.com/settings](https://smith.langchain.com/settings) 10 | 11 | Step 3: Add these 2 environment variables: 12 | 13 | ```bash 14 | LANGCHAIN_TRACING_V2=true 15 | LANGCHAIN_API_KEY=Set this to your API key 16 | ``` 17 | 18 | Here's what this looks like in the Langsmith Dashboard: 19 | 20 | ![Langsmith Dashboard](./langsmith.png) 21 | 22 | This can be helpful for: 23 | 24 | - Enabling users to visualize and inspect the backend data flow 25 | - Quality assurance debugging - where can the input or output of our AI flows use improvement 26 | - Cost analysis - where are we spending the most on LLM calls 27 | - Error analysis - where are we getting the most errors 28 | - Optimizing speed - which parts of the flow are taking the most time 29 | -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/handling-logs/langsmith.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/docs/gpt-researcher/handling-logs/langsmith.png -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/llms/running-with-azure.md: -------------------------------------------------------------------------------- 1 | # Running with Azure 2 | 3 | ## Example: Azure OpenAI Configuration 4 | 5 | If you are not using OpenAI's models, but other model providers, besides the general configuration above, also additional environment variables are required. 6 | 7 | Here is an example for [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models) configuration: 8 | 9 | ```bash 10 | OPENAI_API_VERSION="2024-05-01-preview" # or whatever you are using 11 | AZURE_OPENAI_ENDPOINT="https://CHANGEMEN.openai.azure.com/" # change to the name of your deployment 12 | AZURE_OPENAI_API_KEY="[Your Key]" # change to your API key 13 | 14 | EMBEDDING="azure_openai:text-embedding-ada-002" # change to the deployment of your embedding model 15 | 16 | FAST_LLM="azure_openai:gpt-4o-mini" # change to the name of your deployment (not model-name) 17 | FAST_TOKEN_LIMIT=4000 18 | 19 | SMART_LLM="azure_openai:gpt-4o" # change to the name of your deployment (not model-name) 20 | SMART_TOKEN_LIMIT=4000 21 | 22 | RETRIEVER="bing" # if you are using Bing as your search engine (which is likely if you use Azure) 23 | BING_API_KEY="[Your Key]" 24 | ``` 25 | 26 | For more details on what each variable does, you can check out the [GPTR Config Docs](https://docs.gptr.dev/docs/gpt-researcher/gptr/config) -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/llms/supported-llms.md: -------------------------------------------------------------------------------- 1 | # Supported LLMs 2 | 3 | The following LLMs are supported by GPTR (though you'll need to install the relevant langchain package separately if you're not using OpenAI). 4 | 5 | - openai 6 | - anthropic 7 | - azure_openai 8 | - cohere 9 | - google_vertexai 10 | - google_genai 11 | - fireworks 12 | - gigachat 13 | - ollama 14 | - together 15 | - mistralai 16 | - huggingface 17 | - groq 18 | - bedrock 19 | - dashscope 20 | - xai 21 | - deepseek 22 | - litellm 23 | - openrouter 24 | - vllm 25 | 26 | If you'd like to know the name of the langchain package for each LLM, you can check the [Langchain documentation](https://python.langchain.com/v0.2/docs/integrations/platforms/), or run GPTR as is and inspect the error message. 27 | 28 | The GPTR LLM Module is built on top of the [Langchain LLM Module](https://python.langchain.com/v0.2/docs/integrations/llms/). 29 | 30 | If you'd like to add a new LLM into GPTR, you can start with the [langchain documentation](https://python.langchain.com/v0.2/docs/integrations/platforms/) and then look into integrating it into the [GPTR LLM Module](https://github.com/assafelovic/gpt-researcher/blob/master/gpt_researcher/llm_provider/generic/base.py). -------------------------------------------------------------------------------- /docs/docs/gpt-researcher/llms/testing-your-llm.md: -------------------------------------------------------------------------------- 1 | # Testing your LLM 2 | 3 | Here is a snippet of code to help you verify that your LLM-related environment variables are set up correctly. 4 | 5 | ```python 6 | from gpt_researcher.config.config import Config 7 | from gpt_researcher.utils.llm import create_chat_completion 8 | import asyncio 9 | from dotenv import load_dotenv 10 | load_dotenv() 11 | 12 | async def main(): 13 | cfg = Config() 14 | 15 | try: 16 | report = await create_chat_completion( 17 | model=cfg.smart_llm_model, 18 | messages = [{"role": "user", "content": "sup?"}], 19 | temperature=0.35, 20 | llm_provider=cfg.smart_llm_provider, 21 | stream=True, 22 | max_tokens=cfg.smart_token_limit, 23 | llm_kwargs=cfg.llm_kwargs 24 | ) 25 | except Exception as e: 26 | print(f"Error in calling LLM: {e}") 27 | 28 | # Run the async function 29 | asyncio.run(main()) 30 | ``` -------------------------------------------------------------------------------- /docs/docs/reference/config/singleton.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: singleton 3 | title: config.singleton 4 | --- 5 | 6 | The singleton metaclass for ensuring only one instance of a class. 7 | 8 | ## Singleton Objects 9 | 10 | ```python 11 | class Singleton(abc.ABCMeta, type) 12 | ``` 13 | 14 | Singleton metaclass for ensuring only one instance of a class. 15 | 16 | #### \_\_call\_\_ 17 | 18 | ```python 19 | def __call__(cls, *args, **kwargs) 20 | ``` 21 | 22 | Call method for the singleton metaclass. 23 | 24 | ## AbstractSingleton Objects 25 | 26 | ```python 27 | class AbstractSingleton(abc.ABC, metaclass=Singleton) 28 | ``` 29 | 30 | Abstract singleton class for ensuring only one instance of a class. 31 | 32 | -------------------------------------------------------------------------------- /docs/docs/reference/processing/html.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_label: html 3 | title: processing.html 4 | --- 5 | 6 | HTML processing functions 7 | 8 | #### extract\_hyperlinks 9 | 10 | ```python 11 | def extract_hyperlinks(soup: BeautifulSoup, 12 | base_url: str) -> list[tuple[str, str]] 13 | ``` 14 | 15 | Extract hyperlinks from a BeautifulSoup object 16 | 17 | **Arguments**: 18 | 19 | - `soup` _BeautifulSoup_ - The BeautifulSoup object 20 | - `base_url` _str_ - The base URL 21 | 22 | 23 | **Returns**: 24 | 25 | List[Tuple[str, str]]: The extracted hyperlinks 26 | 27 | #### format\_hyperlinks 28 | 29 | ```python 30 | def format_hyperlinks(hyperlinks: list[tuple[str, str]]) -> list[str] 31 | ``` 32 | 33 | Format hyperlinks to be displayed to the user 34 | 35 | **Arguments**: 36 | 37 | - `hyperlinks` _List[Tuple[str, str]]_ - The hyperlinks to format 38 | 39 | 40 | **Returns**: 41 | 42 | - `List[str]` - The formatted hyperlinks 43 | 44 | -------------------------------------------------------------------------------- /docs/docs/reference/sidebar.json: -------------------------------------------------------------------------------- 1 | { 2 | "items": [], 3 | "label": "Reference", 4 | "type": "category" 5 | } -------------------------------------------------------------------------------- /docs/docs/roadmap.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | We're constantly working on additional features and improvements to our products and services. We're also working on new products and services to help you build better AI applications using [GPT Researcher](https://gptr.dev). 4 | 5 | Our vision is to build the #1 autonomous research agent for AI developers and researchers, and we're excited to have you join us on this journey! 6 | 7 | The roadmap is prioritized based on the following goals: Performance, Quality, Modularity and Conversational flexibility. The roadmap is public and can be found [here](https://trello.com/b/3O7KBePw/gpt-researcher-roadmap). 8 | 9 | Interested in collaborating or contributing? Check out our [contributing page](/docs/contribute) for more information. -------------------------------------------------------------------------------- /docs/docs/welcome.md: -------------------------------------------------------------------------------- 1 | # Welcome 2 | 3 | Hey there! 👋 4 | 5 | We're a team of AI researchers and developers who are passionate about building the next generation of AI assistants. 6 | Our mission is to empower individuals and organizations with accurate, unbiased, and factual information. 7 | 8 | ### GPT Researcher 9 | Quickly accessing relevant and trustworthy information is more crucial than ever. However, we've learned that none of today's search engines provide a suitable tool that provides factual, explicit and objective answers without the need to continuously click and explore multiple sites for a given research task. 10 | 11 | This is why we've built the trending open source **[GPT Researcher](https://github.com/assafelovic/gpt-researcher)**. GPT Researcher is an autonomous agent that takes care of the tedious task of research for you, by scraping, filtering and aggregating over 20+ web sources per a single research task. 12 | 13 | To learn more about GPT Researcher, check out the [documentation page](/docs/gpt-researcher/getting-started/introduction). 14 | -------------------------------------------------------------------------------- /docs/npm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gpt-researcher", 3 | "version": "1.0.27", 4 | "description": "WebSocket client for GPT Researcher", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "gpt-researcher", 11 | "websocket", 12 | "ai", 13 | "research" 14 | ], 15 | "dependencies": { 16 | "ws": "^8.18.0" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/assafelovic/gpt-researcher.git" 21 | }, 22 | "author": "GPT Researcher Team", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/assafelovic/gpt-researcher/issues" 26 | }, 27 | "homepage": "https://github.com/assafelovic/gpt-researcher#readme" 28 | } -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "version": "0.0.0", 4 | "private": true, 5 | "resolutions": { 6 | "nth-check": "2.0.1", 7 | "trim": "0.0.3", 8 | "got": "11.8.5", 9 | "node-forge": "1.3.0", 10 | "minimatch": "3.0.5", 11 | "loader-utils": "2.0.4", 12 | "eta": "2.0.0", 13 | "@sideway/formula": "3.0.1", 14 | "http-cache-semantics": "4.1.1" 15 | }, 16 | "scripts": { 17 | "docusaurus": "docusaurus", 18 | "start": "docusaurus start", 19 | "build": "docusaurus build", 20 | "swizzle": "docusaurus swizzle", 21 | "deploy": "docusaurus deploy", 22 | "clear": "docusaurus clear", 23 | "serve": "docusaurus serve", 24 | "write-translations": "docusaurus write-translations", 25 | "write-heading-ids": "docusaurus write-heading-ids" 26 | }, 27 | "dependencies": { 28 | "@docusaurus/core": "3.7.0", 29 | "@docusaurus/preset-classic": "3.7.0", 30 | "@easyops-cn/docusaurus-search-local": "^0.49.2", 31 | "@mdx-js/react": "^3.1.0", 32 | "@svgr/webpack": "^8.1.0", 33 | "clsx": "^1.1.1", 34 | "file-loader": "^6.2.0", 35 | "hast-util-is-element": "1.1.0", 36 | "minimatch": "3.0.5", 37 | "react": "^18.0.1", 38 | "react-dom": "^18.0.1", 39 | "rehype-katex": "^7.0.1", 40 | "remark-math": "3", 41 | "trim": "^0.0.3", 42 | "url-loader": "^4.1.1" 43 | }, 44 | "browserslist": { 45 | "production": [ 46 | ">0.5%", 47 | "not dead", 48 | "not op_mini all" 49 | ], 50 | "development": [ 51 | "last 1 chrome version", 52 | "last 1 firefox version", 53 | "last 1 safari version" 54 | ] 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /docs/pydoc-markdown.yml: -------------------------------------------------------------------------------- 1 | loaders: 2 | - type: python 3 | search_path: [../docs] 4 | processors: 5 | - type: filter 6 | skip_empty_modules: true 7 | - type: smart 8 | - type: crossref 9 | renderer: 10 | type: docusaurus 11 | docs_base_path: docs 12 | relative_output_path: reference 13 | relative_sidebar_path: sidebar.json 14 | sidebar_top_level_label: Reference 15 | markdown: 16 | escape_html_in_docstring: false 17 | -------------------------------------------------------------------------------- /docs/src/components/HomepageFeatures.module.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | 3 | .features { 4 | display: flex; 5 | align-items: center; 6 | padding: 2rem 0; 7 | width: 100%; 8 | } 9 | 10 | .featureSvg { 11 | height: 120px; 12 | width: 200px; 13 | } 14 | -------------------------------------------------------------------------------- /docs/src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import Layout from '@theme/Layout'; 4 | import Link from '@docusaurus/Link'; 5 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 6 | import styles from './index.module.css'; 7 | import HomepageFeatures from '../components/HomepageFeatures'; 8 | 9 | function HomepageHeader() { 10 | const {siteConfig} = useDocusaurusContext(); 11 | return ( 12 |
13 |
14 |

{siteConfig.title}

15 |

{siteConfig.tagline}

16 |
17 | 20 | Getting Started - 5 min ⏱️ 21 | 22 |
23 |
24 |
25 | ); 26 | } 27 | 28 | export default function Home() { 29 | const {siteConfig} = useDocusaurusContext(); 30 | return ( 31 | 34 | 35 |
36 | 37 |
38 |
39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /docs/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | 3 | /** 4 | * CSS files with the .module.css suffix will be treated as CSS modules 5 | * and scoped locally. 6 | */ 7 | 8 | .heroBanner { 9 | padding: 5rem 0; 10 | text-align: center; 11 | position: relative; 12 | overflow: hidden; 13 | } 14 | 15 | @media screen and (max-width: 966px) { 16 | .heroBanner { 17 | padding: 2rem; 18 | } 19 | } 20 | 21 | .buttons { 22 | display: flex; 23 | align-items: center; 24 | justify-content: center; 25 | } 26 | -------------------------------------------------------------------------------- /docs/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/static/.nojekyll -------------------------------------------------------------------------------- /docs/static/CNAME: -------------------------------------------------------------------------------- 1 | docs.gptr.dev -------------------------------------------------------------------------------- /docs/static/img/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/static/img/architecture.png -------------------------------------------------------------------------------- /docs/static/img/banner1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/static/img/banner1.jpg -------------------------------------------------------------------------------- /docs/static/img/examples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/static/img/examples.png -------------------------------------------------------------------------------- /docs/static/img/gptr-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/static/img/gptr-logo.png -------------------------------------------------------------------------------- /docs/static/img/leaderboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/static/img/leaderboard.png -------------------------------------------------------------------------------- /docs/static/img/multi-agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/docs/static/img/multi-agent.png -------------------------------------------------------------------------------- /evals/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/evals/__init__.py -------------------------------------------------------------------------------- /evals/simple_evals/.gitignore: -------------------------------------------------------------------------------- 1 | # Override global gitignore to track our evaluation logs 2 | !logs/ 3 | !logs/* 4 | !logs/**/* -------------------------------------------------------------------------------- /evals/simple_evals/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/evals/simple_evals/__init__.py -------------------------------------------------------------------------------- /evals/simple_evals/logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assafelovic/gpt-researcher/9d085d867fce49c24cf296659eebf5d7595cbed2/evals/simple_evals/logs/.gitkeep -------------------------------------------------------------------------------- /evals/simple_evals/logs/README.md: -------------------------------------------------------------------------------- 1 | # Evaluation Results 2 | 3 | This directory contains historical evaluation results for GPT-Researcher using the SimpleQA methodology. 4 | 5 | ## Latest Results 6 | 7 | ### [SimpleQA Eval 100 Problems 2-22-25](./SimpleQA%20Eval%20100%20Problems%202-22-25.txt) 8 | 9 | Evaluation run by [Kelly Abbott (kga245)](https://github.com/kga245) 10 | 11 | **Summary:** 12 | - Date: February 22, 2025 13 | - Sample Size: 100 queries 14 | - Success Rate: 100% (100/100 queries completed) 15 | 16 | **Performance Metrics:** 17 | - Accuracy: 92.9% 18 | - F1 Score: 92.5% 19 | - Answer Rate: 99% 20 | 21 | **Response Distribution:** 22 | - Correct: 92% 23 | - Incorrect: 7% 24 | - Not Attempted: 1% 25 | 26 | **Cost Efficiency:** 27 | - Total Cost: $9.60 28 | - Average Cost per Query: $0.096 29 | 30 | This evaluation demonstrates strong performance in factual accuracy while maintaining reasonable cost efficiency. The high answer rate (99%) and accuracy (92.9%) suggest that GPT-Researcher is effective at finding and reporting accurate information. 31 | 32 | ## Historical Context 33 | 34 | These logs are maintained in version control to: 35 | 1. Track performance improvements over time 36 | 2. Provide benchmarks for future enhancements 37 | 3. Enable analysis of different configurations 38 | 4. Ensure transparency in our evaluation process 39 | 40 | Each log file contains detailed information about: 41 | - Individual query results 42 | - Source citations 43 | - Cost breakdowns 44 | - Error analysis 45 | - Aggregate metrics 46 | 47 | ## Running New Evaluations 48 | 49 | To generate new evaluation logs, see the [main evaluation documentation](../README.md) for instructions on running evaluations with different configurations or sample sizes. -------------------------------------------------------------------------------- /evals/simple_evals/requirements.txt: -------------------------------------------------------------------------------- 1 | pandas>=1.5.0 2 | tqdm>=4.65.0 -------------------------------------------------------------------------------- /frontend/nextjs/.babelrc.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "production": { 4 | "presets": [ 5 | "@babel/preset-env", 6 | "@babel/preset-react", 7 | ["@babel/preset-typescript", { "allowNamespaces": true, "onlyRemoveTypeImports": true }] 8 | ], 9 | "plugins": [ 10 | ["@babel/plugin-transform-typescript", { "allowNamespaces": true }] 11 | ] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /frontend/nextjs/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | 3 | # Ignore env containing secrets 4 | .env 5 | .venv 6 | .envrc 7 | 8 | # Ignore Virtual Env 9 | env/ 10 | venv/ 11 | .venv/ 12 | 13 | # Other Environments 14 | ENV/ 15 | env.bak/ 16 | venv.bak/ 17 | 18 | # Ignore generated outputs 19 | outputs/ 20 | 21 | # Ignore my local docs 22 | my-docs/ 23 | 24 | # Ignore pycache 25 | **/__pycache__/ 26 | 27 | # Ignore mypy cache 28 | .mypy_cache/ 29 | 30 | # Node modules 31 | node_modules 32 | 33 | # Ignore IDE config 34 | .idea 35 | 36 | # macOS specific files 37 | .DS_Store 38 | 39 | # Docusaurus build artifacts 40 | .docusaurus 41 | 42 | # Build directories 43 | build 44 | docs/build 45 | 46 | # Language graph data 47 | .langgraph-data/ 48 | 49 | # Next.js build artifacts 50 | .next/ 51 | 52 | # Package lock file 53 | package-lock.json 54 | 55 | # Docker-specific exclusions (if any) 56 | Dockerfile 57 | docker-compose.yml 58 | -------------------------------------------------------------------------------- /frontend/nextjs/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals", 3 | "rules": { 4 | "no-unused-vars": "off", 5 | "no-undef": "off", 6 | "no-console": "off", 7 | "@next/next/no-img-element": "off", 8 | "@typescript-eslint/no-explicit-any": "off", 9 | "@typescript-eslint/no-unused-vars": "off" 10 | }, 11 | "ignorePatterns": ["build/**/*"] 12 | } 13 | -------------------------------------------------------------------------------- /frontend/nextjs/.example.env: -------------------------------------------------------------------------------- 1 | TOGETHER_API_KEY= 2 | BING_API_KEY= 3 | HELICONE_API_KEY= 4 | -------------------------------------------------------------------------------- /frontend/nextjs/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | .env 3 | package-lock.json 4 | 5 | # dependencies 6 | /node_modules 7 | /.pnp 8 | .pnp.js 9 | .yarn/install-state.gz 10 | 11 | # testing 12 | /coverage 13 | 14 | # next.js 15 | /.next/ 16 | /out/ 17 | 18 | # production 19 | /build 20 | 21 | # misc 22 | .DS_Store 23 | *.pem 24 | 25 | # debug 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | 30 | # local env files 31 | .env*.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | next-env.d.ts 39 | -------------------------------------------------------------------------------- /frontend/nextjs/.prettierrc: -------------------------------------------------------------------------------- 1 | { "plugins": ["prettier-plugin-tailwindcss"] } 2 | -------------------------------------------------------------------------------- /frontend/nextjs/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18.17.0-alpine as builder 2 | WORKDIR /app 3 | COPY ./package.json ./ 4 | RUN npm install --legacy-peer-deps 5 | COPY . . 6 | RUN npm run build 7 | 8 | FROM nginx 9 | EXPOSE 3000 10 | COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf 11 | COPY --from=builder /app/build /usr/share/nginx/html 12 | -------------------------------------------------------------------------------- /frontend/nextjs/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM node:18.17.0-alpine 2 | WORKDIR /app 3 | COPY ./package.json ./ 4 | RUN npm install --legacy-peer-deps 5 | COPY . . 6 | CMD ["npm", "run", "dev"] -------------------------------------------------------------------------------- /frontend/nextjs/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Lexend } from "next/font/google"; 3 | import PlausibleProvider from "next-plausible"; 4 | import { GoogleAnalytics } from '@next/third-parties/google' 5 | import "./globals.css"; 6 | 7 | const inter = Lexend({ subsets: ["latin"] }); 8 | 9 | let title = "GPT Researcher"; 10 | let description = 11 | "LLM based autonomous agent that conducts local and web research on any topic and generates a comprehensive report with citations."; 12 | let url = "https://github.com/assafelovic/gpt-researcher"; 13 | let ogimage = "/favicon.ico"; 14 | let sitename = "GPT Researcher"; 15 | 16 | export const metadata: Metadata = { 17 | metadataBase: new URL(url), 18 | title, 19 | description, 20 | icons: { 21 | icon: "/favicon.ico", 22 | }, 23 | openGraph: { 24 | images: [ogimage], 25 | title, 26 | description, 27 | url: url, 28 | siteName: sitename, 29 | locale: "en_US", 30 | type: "website", 31 | }, 32 | twitter: { 33 | card: "summary_large_image", 34 | images: [ogimage], 35 | title, 36 | description, 37 | }, 38 | }; 39 | 40 | export default function RootLayout({ 41 | children, 42 | }: Readonly<{ 43 | children: React.ReactNode; 44 | }>) { 45 | 46 | return ( 47 | 48 | 49 | 50 | 51 | 52 | 56 | {children} 57 | 58 | 59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /frontend/nextjs/components/HumanFeedback.tsx: -------------------------------------------------------------------------------- 1 | // /multi_agents/frontend/components/HumanFeedback.tsx 2 | 3 | import React, { useState, useEffect } from 'react'; 4 | 5 | interface HumanFeedbackProps { 6 | websocket: WebSocket | null; 7 | onFeedbackSubmit: (feedback: string | null) => void; 8 | questionForHuman: boolean; 9 | } 10 | 11 | const HumanFeedback: React.FC = ({ questionForHuman, websocket, onFeedbackSubmit }) => { 12 | const [feedbackRequest, setFeedbackRequest] = useState(null); 13 | const [userFeedback, setUserFeedback] = useState(''); 14 | 15 | const handleSubmit = (e: React.FormEvent) => { 16 | e.preventDefault(); 17 | onFeedbackSubmit(userFeedback === '' ? null : userFeedback); 18 | setFeedbackRequest(null); 19 | setUserFeedback(''); 20 | }; 21 | 22 | return ( 23 |
24 |

Human Feedback Required

25 |

{questionForHuman}

26 |
27 |