Skip to content

crastatelvin/nexus-research

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🧠 NEXUS Research

A Multi-Agent AI Research Workspace β€” Watch Four Agents Turn a Question Into a Structured Brief

Python FastAPI React Vite Tailwind Groq License: MIT


NEXUS Research is a full-stack multi-agent AI application that transforms a single research question into a structured executive brief. Four specialized agents β€” SCOUT, ANALYST, CRITIC, and SCRIBE β€” collaborate through a live pipeline powered by Groq LLaMA 3.3 / 3.1 models, streaming their progress over WebSockets while rendering a real-time agent topology graph, source evidence, adversarial critique, and an exportable PDF report.


Multi-Agent Live Pipeline Token Optimized


πŸ“‹ Table of Contents


🧠 Overview

NEXUS Research is a demonstration of how a small, transparent pipeline of specialized LLM agents can outperform a single monolithic prompt β€” and do it on a Groq free-tier budget. Instead of hiding reasoning behind one opaque call, NEXUS decomposes the research task into four visible stages and streams every intermediate state to the browser.

Users can:

  • Enter a plain-English research question, pick a depth (standard / deep) and a mode (auto / live / demo)
  • Watch a live ReactFlow agent graph animate as each agent takes over β€” powered by a FastAPI WebSocket
  • See sources, findings, synthesis, critique, and the final brief populate the UI in real time
  • Export the completed brief as a branded, searchable PDF with one click
  • Run fully offline in demo mode (deterministic content, no API key required)

The backend is built with FastAPI and uses the Groq Python SDK against llama-3.3-70b-versatile and llama-3.1-8b-instant, with DuckDuckGo (AsyncDDGS + httpx HTML fallback) for web search and BeautifulSoup for page scraping. Every agent has its own model, temperature, and token cap β€” routed to keep a full run under a ~12k token budget on the free tier.


πŸ–ΌοΈ Application Preview

Landing Page

Landing Page

Live Agent Topology (Run in Progress)

Live Agent Graph

Agent Status Cards + Live Event Feed

Agent Cards and Live Feed

Discovered Sources & Critique Panel

Sources and Critique

Final Research Report

Research Report

Exported PDF Brief

PDF Export


✨ Features

Feature Description
πŸ”Ž SCOUT Agent Expands a single question into 3–12 targeted search queries, then hits DuckDuckGo (async) and dedupes / de-ads the results
πŸ“š ANALYST Agent Fetches each source, extracts the top findings with Groq, and synthesizes themes, consensus, conflicts, and knowledge gaps
πŸ§‘β€βš–οΈ CRITIC Agent Adversarially reviews the synthesis for logical flaws, missing perspectives, bias risk, overstatements, and reliability concerns
✍️ SCRIBE Agent Produces the final executive brief: summary, background, analysis, critical perspectives, key findings, recommendations, conclusion
πŸ“‘ Live WebSocket Stream Normalized agent events (running / searching / reading / complete / error) push to the browser as they happen
🌐 ReactFlow Topology Graph Animated live pipeline visualization β€” edges flow when agents are active, colors match agent roles
πŸ’Ύ Semantic Prompt Cache Hash-based response cache keyed on (prompt + model + schema) β€” reused identical prompts cost zero tokens
πŸ’Έ Per-Run Token Budget Hard guardrail (default 12k tokens/run) stops the pipeline gracefully before the Groq free tier runs dry
🎯 Model Routing Cheap llama-3.1-8b-instant for SCOUT planning, llama-3.3-70b-versatile for ANALYST/CRITIC/SCRIBE
πŸ” Graceful Fallback If DuckDuckGo rate-limits or scraping fails, SCOUT falls back to deterministic demo sources so the run never hangs
πŸ“„ Native PDF Export Text-based jsPDF export β€” selectable, searchable, and not broken by Tailwind v4 oklch() colors
πŸ§ͺ Fully Tested Pytest on the backend, Vitest + Testing Library on the frontend, both green

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       Browser / React 19 + Vite                     β”‚
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ LandingPageβ”‚  β”‚ AgentGraph   β”‚  β”‚ LiveFeed     β”‚  β”‚ Research  β”‚  β”‚
β”‚  β”‚ (Question +β”‚  β”‚ (ReactFlow β€” β”‚  β”‚ (WebSocket   β”‚  β”‚ Report +  β”‚  β”‚
β”‚  β”‚  Depth +   β”‚  β”‚  live edges  β”‚  β”‚  events feed)β”‚  β”‚ PDF Exportβ”‚  β”‚
β”‚  β”‚   Mode)    β”‚  β”‚  animated)   β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚                β”‚        β”‚
β”‚        β”‚ POST /research β”‚   GET /research/:id    WS /ws    β”‚        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                β”‚                 β”‚                β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       FastAPI Backend (main.py)                     β”‚
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                    Agent Pipeline (sequential)                β”‚  β”‚
β”‚  β”‚                                                               β”‚  β”‚
β”‚  β”‚   SCOUT  ──►  ANALYST  ──►  CRITIC  ──►  SCRIBE               β”‚  β”‚
β”‚  β”‚   (plan +     (fetch +       (review +    (final brief)       β”‚  β”‚
β”‚  β”‚    search)     extract +      flag bias)                      β”‚  β”‚
β”‚  β”‚                synthesize)                                    β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  groq_service.py   β”‚  β”‚ search_service  β”‚  β”‚  scraper_service β”‚  β”‚
β”‚  β”‚  β€’ model routing   β”‚  β”‚ β€’ AsyncDDGS +   β”‚  β”‚  β€’ httpx + bs4   β”‚  β”‚
β”‚  β”‚  β€’ prompt cache    β”‚  β”‚   httpx fallbackβ”‚  β”‚  β€’ concurrent    β”‚  β”‚
β”‚  β”‚  β€’ token budget    β”‚  β”‚ β€’ ad/redirect   β”‚  β”‚    fetch         β”‚  β”‚
β”‚  β”‚  β€’ JSON retries    β”‚  β”‚   filter        β”‚  β”‚                  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  run_store.py      β”‚  β”‚ demo_service.py β”‚  β”‚  settings.py     β”‚  β”‚
β”‚  β”‚  In-memory run     β”‚  β”‚ Deterministic   β”‚  β”‚  env-driven      β”‚  β”‚
β”‚  β”‚  state + events    β”‚  β”‚ fallback path   β”‚  β”‚  config dataclassβ”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚   Groq Cloud API      β”‚
                    β”‚ llama-3.3-70b + 3.1-8bβ”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ› οΈ Tech Stack

Layer Technology
Frontend React 19, Vite 8, Tailwind CSS 4, Framer Motion, @xyflow/react, Axios, jsPDF
Backend FastAPI, Uvicorn, Pydantic 2, Python 3.11+
LLM Provider Groq Cloud β€” llama-3.3-70b-versatile (ANALYST / CRITIC / SCRIBE), llama-3.1-8b-instant (SCOUT)
Web Search duckduckgo-search (AsyncDDGS) with httpx HTML fallback
Scraping httpx + BeautifulSoup4
Streaming Native FastAPI WebSockets with JSON-encoded AgentEvent broadcasts
Testing Pytest (backend), Vitest + Testing Library (frontend)
Export jspdf (native text PDF β€” no screenshot step, no oklch() issues)

πŸ“ Project Structure

nexus-research/
β”‚
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ main.py                     # FastAPI app β€” /research, /research/:id, /latest, /status, /ws
β”‚   β”œβ”€β”€ requirements.txt            # Python deps
β”‚   β”œβ”€β”€ .env                        # GROQ_API_KEY + token caps + model routing
β”‚   β”‚
β”‚   β”œβ”€β”€ agents/
β”‚   β”‚   β”œβ”€β”€ scout.py                # Query planning + web search
β”‚   β”‚   β”œβ”€β”€ analyst.py              # Source reading + extraction + synthesis
β”‚   β”‚   β”œβ”€β”€ critic.py               # Adversarial review + confidence rating
β”‚   β”‚   └── scribe.py               # Final executive brief synthesis
β”‚   β”‚
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ groq_service.py         # Groq SDK wrapper, prompt cache, token budget
β”‚   β”‚   β”œβ”€β”€ search_service.py       # AsyncDDGS + httpx fallback + ad filter
β”‚   β”‚   β”œβ”€β”€ scraper_service.py      # httpx + BeautifulSoup page fetcher
β”‚   β”‚   β”œβ”€β”€ demo_service.py         # Deterministic offline pipeline
β”‚   β”‚   β”œβ”€β”€ run_store.py            # In-memory run state + event log
β”‚   β”‚   └── settings.py             # Env-driven dataclass config
β”‚   β”‚
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   └── schemas.py              # Pydantic models β€” coercive validators for robust LLM JSON
β”‚   β”‚
β”‚   └── tests/
β”‚       └── test_api.py             # Pytest suite β€” demo-mode end-to-end
β”‚
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ App.jsx                 # Root β€” landing ↔ research workspace
β”‚   β”‚   β”œβ”€β”€ main.jsx                # Vite entry
β”‚   β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   β”‚   β”œβ”€β”€ LandingPage.jsx     # Hero + preview cards + start form
β”‚   β”‚   β”‚   └── ResearchPage.jsx    # Live workspace β€” graph, feed, sources, report
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ AgentGraph.jsx      # ReactFlow topology with animated edges
β”‚   β”‚   β”‚   β”œβ”€β”€ AgentCard.jsx       # Per-agent status card with live pulse
β”‚   β”‚   β”‚   β”œβ”€β”€ LiveFeed.jsx        # Scrollable WebSocket event log
β”‚   β”‚   β”‚   β”œβ”€β”€ ProgressRing.jsx    # Conic-gradient pipeline progress
β”‚   β”‚   β”‚   β”œβ”€β”€ SearchBar.jsx       # Question + depth + mode form
β”‚   β”‚   β”‚   β”œβ”€β”€ SourceCard.jsx      # Favicon + domain + snippet + numbered badge
β”‚   β”‚   β”‚   β”œβ”€β”€ CritiquePanel.jsx   # Adversarial findings + confidence chip
β”‚   β”‚   β”‚   β”œβ”€β”€ ResearchReport.jsx  # Final report sections
β”‚   β”‚   β”‚   └── ExportButton.jsx    # Native jsPDF export
β”‚   β”‚   β”œβ”€β”€ hooks/
β”‚   β”‚   β”‚   β”œβ”€β”€ useResearch.js      # Run lifecycle, polling, 404 recovery
β”‚   β”‚   β”‚   └── useWebSocket.js     # Reconnecting WS client
β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”‚   β”œβ”€β”€ api.js              # Axios wrappers
β”‚   β”‚   β”‚   └── agentMeta.js        # Agent colors, tones, status enums
β”‚   β”‚   └── styles/
β”‚   β”‚       └── globals.css         # Tailwind + custom panel / graph styles
β”‚   β”œβ”€β”€ package.json
β”‚   └── vite.config.js
β”‚
β”œβ”€β”€ sample_outputs/
β”‚   └── sample_report.md            # Example completed research brief
β”‚
β”œβ”€β”€ docs/
β”‚   └── screenshots/                # README preview images
β”‚
β”œβ”€β”€ DECISIONS.md                    # Architecture decisions + trade-offs
└── README.md

πŸš€ Installation

Prerequisites

  • Python 3.11+
  • Node.js 18+
  • A Groq API key (free tier works great) β€” optional if you only want demo mode

1. Clone the Repository

git clone https://github.com/your-username/nexus-research.git
cd nexus-research

2. Backend Setup

cd backend
python -m venv .venv

# Activate virtual environment
source .venv/bin/activate        # Linux / macOS
.venv\Scripts\Activate.ps1       # Windows PowerShell

pip install -r requirements.txt

3. Configure Environment Variables

Create a .env file inside backend/:

# Groq (optional β€” leave empty to force demo mode)
GROQ_API_KEY=your_groq_api_key_here

# Model routing (optional β€” these are the defaults)
GROQ_MODEL_SCOUT=llama-3.1-8b-instant
GROQ_MODEL_ANALYST=llama-3.3-70b-versatile
GROQ_MODEL_CRITIC=llama-3.3-70b-versatile
GROQ_MODEL_SCRIBE=llama-3.3-70b-versatile

# Token caps per agent call (optional β€” defaults shown)
NEXUS_TOKEN_CAP_SCOUT=320
NEXUS_TOKEN_CAP_ANALYST_EXTRACT=700
NEXUS_TOKEN_CAP_ANALYST_SYNTHESIS=600
NEXUS_TOKEN_CAP_CRITIC=600
NEXUS_TOKEN_CAP_SCRIBE=1000

# Per-run hard budget β€” pipeline stops gracefully if exceeded
NEXUS_TOKEN_BUDGET_PER_RUN=12000

# Search timeout (seconds)
NEXUS_SEARCH_TIMEOUT_SECONDS=12.0

4. Start the Backend

uvicorn main:app --reload --host 127.0.0.1 --port 8000

API runs at http://localhost:8000 Β· Interactive docs at http://localhost:8000/docs

5. Frontend Setup

cd ../frontend
npm install

Create a .env file in frontend/ (optional β€” these are the defaults):

VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000/ws

6. Start the Frontend

npm run dev

Frontend runs at http://localhost:5173


πŸ’» Usage

Starting a Research Run

  1. Open the app at http://localhost:5173
  2. Type a research question β€” e.g. "How are research teams using AI in due diligence?"
  3. Choose a Depth: standard (3 sources) or deep (5 sources)
  4. Choose a Mode:
    • auto β€” use Groq if the key is set, otherwise fall back to demo
    • live β€” require Groq (errors if no key)
    • demo β€” deterministic local content, no API calls
  5. Click Start Research

Watching the Pipeline

The research workspace shows everything that happens in real time:

  • Run topology graph β€” animated ReactFlow edges flow between SCOUT β†’ ANALYST β†’ CRITIC β†’ SCRIBE as each agent takes over
  • Progress ring β€” conic gradient shows how many of the four agents are complete
  • Live feed β€” every WebSocket event (searching, reading, challenging, writing, …) streams in
  • Agent cards β€” per-agent status, current message, and live pulsing indicator

Reading the Report

When SCRIBE finishes, three panels populate:

  • Discovered Evidence β€” every source kept, with favicon, domain chip, snippet, and numbered badge
  • Critic Review β€” adversarial findings grouped by category, with a color-coded confidence badge (HIGH / MEDIUM / LOW) and justification
  • Final Report β€” Executive Summary, Background, Analysis, Critical Perspectives, Conclusion, Key Findings, Recommendations, Cited Sources

Exporting as PDF

Click Export PDF at the top of the final report. NEXUS generates a native text PDF (selectable, searchable, branded with cover header and page footers) β€” no screenshot step, no color-parsing issues.


πŸ€– The Four Agents

Agent Role Default Model Output
🟑 SCOUT Web reconnaissance llama-3.1-8b-instant 3–12 search queries, deduped ranked sources
πŸ”΅ ANALYST Evidence extraction llama-3.3-70b-versatile Per-source findings + synthesis (themes, consensus, conflicts, gaps)
πŸ”΄ CRITIC Adversarial review llama-3.3-70b-versatile Logical flaws, missing perspectives, bias risk, overstatements, confidence rating
🟣 SCRIBE Report synthesis llama-3.3-70b-versatile Full executive brief: 5 prose sections + key findings + recommendations

Each agent runs sequentially, emits structured WebSocket events (running β†’ working status β†’ complete), and pipes its output into the next agent's context.


πŸ’Έ Token Optimization

NEXUS is engineered to run a full 4-agent pipeline inside the Groq free-tier budget. Key techniques applied in groq_service.py and settings.py:

Technique Impact
Model routing SCOUT (planning) uses the cheap 8B model; heavy reasoning agents use 70B
Strict per-agent max_tokens Hard caps stop verbose outputs before they bloat the next agent's prompt
Low temperatures (0.1–0.3) Deterministic outputs = fewer retries
Semantic prompt cache Hash (normalized_prompt + model + schema) β€” identical repeats cost 0 tokens
Field pruning in prompts Only top-N findings pass to CRITIC / SCRIBE instead of the full set
Per-run token budget NEXUS_TOKEN_BUDGET_PER_RUN β€” pipeline returns a partial report rather than failing hard
JSON retry guardrail Smart retries on malformed JSON avoid silent token waste on invalid completions

πŸ”Œ API Reference

Method Endpoint Description
POST /research Create a new research run. Body: { question, depth, mode }
GET /research/{run_id} Fetch current run status + result (if complete)
GET /latest Fetch the most recent completed run
GET /status API health + whether Groq is configured
WS /ws Stream normalized AgentEvent objects for all active runs

Example β€” start a run:

curl -X POST http://localhost:8000/research \
  -H "Content-Type: application/json" \
  -d '{"question":"How are research teams using AI in due diligence?","depth":"standard","mode":"auto"}'

Example AgentEvent broadcast:

{
  "run_id": "a1b2c3d4-...",
  "event": "agent_status",
  "agent": "SCOUT",
  "status": "searching",
  "message": "Running 4 search queries..."
}

βš™οΈ Configuration

Backend (backend/.env)

GROQ_API_KEY=...                            # leave empty to force demo
GROQ_MODEL_SCOUT=llama-3.1-8b-instant
GROQ_MODEL_ANALYST=llama-3.3-70b-versatile
GROQ_MODEL_CRITIC=llama-3.3-70b-versatile
GROQ_MODEL_SCRIBE=llama-3.3-70b-versatile
NEXUS_TOKEN_CAP_SCOUT=320
NEXUS_TOKEN_CAP_ANALYST_EXTRACT=700
NEXUS_TOKEN_CAP_ANALYST_SYNTHESIS=600
NEXUS_TOKEN_CAP_CRITIC=600
NEXUS_TOKEN_CAP_SCRIBE=1000
NEXUS_TOKEN_BUDGET_PER_RUN=12000
NEXUS_SEARCH_TIMEOUT_SECONDS=12.0
CORS_ORIGINS=*                              # restrict in production

Frontend (frontend/.env)

VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000/ws

πŸ”„ Running Modes

Mode Behavior When to use
auto Use Groq if GROQ_API_KEY is set, otherwise fall back to demo Default β€” safe for any environment
live Require Groq. Errors out if no key is configured Production / real research
demo Deterministic offline content, no external calls Screenshots, demos, CI, offline dev

πŸ§ͺ Testing

# Backend β€” Pytest
cd backend
pytest

# Frontend β€” Vitest (single run)
cd ../frontend
npm test -- --run

# Frontend β€” lint + production build
npm run lint
npm run build

πŸ”’ Security Notes

This project is built for local development and demo deployments. Before any public deployment:

  • The backend defaults CORS_ORIGINS=* β€” restrict this to your actual frontend domain
  • run_store.py is an in-memory dict β€” runs don't survive restarts and aren't safe for multi-tenant production use; swap in Redis or a database
  • Never commit your .env or expose GROQ_API_KEY publicly
  • The scraper follows redirects and fetches arbitrary URLs β€” consider adding a domain allowlist and hard timeouts in production (both are already in place as sane defaults)
  • demo mode is a safe fallback that makes no external network calls

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature
  3. Commit your changes: git commit -m 'Add your feature'
  4. Push: git push origin feature/your-feature
  5. Open a Pull Request

Ideas for improvement: persistent run storage (Postgres/Redis), multi-turn follow-up questions, streaming Groq responses directly into the report UI, Docker compose for one-command setup, user authentication, per-user run history, alternative LLM providers (Cerebras, Together, Gemini), adaptive pipeline depth based on confidence, export to DOCX / Notion / Markdown, embedding-based semantic cache.


License

This project is licensed under the MIT License. See LICENSE.

                                Made with ❀️ for anyone who's ever wanted to watch AI agents think out loud.

                                                  ⭐ Star this repo if you find it useful!

About

🧠 Multi-agent AI research platform. Four specialized agents β€” SCOUT, ANALYST, CRITIC & SCRIBE β€” work in sequence to search the web, extract findings, challenge logic & synthesize professional research reports.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors