Stop reading news. Start interacting with it.
AI-powered news intelligence built on Economic Times journalism.
π Live Demo β’ Features β’ Architecture β’ Getting Started β’ API Reference β’ Tech Stack
Business news in 2026 is still delivered like it's 2005 β static text articles, one-size-fits-all homepage, same format for everyone. Build something that makes people say "I can't go back to reading news the old way."
EditoriAI scrapes Economic Times articles in real-time, runs them through a RAG pipeline (chunk, embed, retrieve), and delivers structured intelligence via GPT-4o-mini that you can interact with β personalized feeds, AI briefings, deep dive analysis, and voice-powered Q&A, all grounded in ET journalism.
All articles condensed into one structured story
- Executive summary synthesizing multiple articles
- Data-driven key facts extracted from coverage
- Impact analysis across stakeholder groups with sentiment indicators
- Timeline of events with sentiment tracking
- Suggested follow-up questions to ask the story
Go beyond the briefing with full-page immersive analysis
- Narrative breakdown with detailed sections
- Bull vs Bear analysis with verdict
- Sentiment scoring with directional signals
- Key numbers with context
- ELI5 (Explain Like I'm 5) summary
- Future scenario projections with likelihood and timeframe
Personalized news feed based on your interests
- Select preferred domains during signup (Markets, Tech, Startups, Economy, etc.)
- Curated stories fetched from ET sections matching your interests
- Accessible via a floating sparkle button on the landing page
Ask questions by voice or text β get cited answers
- Real-time voice input powered by Deepgram Nova-2 STT
- Falls back to Web Speech API when Deepgram is unavailable
- Concise, grounded answers with source citations
- Per-question RAG retrieval for focused, relevant answers
- Full-screen chat on mobile, side panel on desktop
Have any briefing or deep dive read aloud
- Text-to-speech powered by Deepgram Aura TTS
- Falls back to browser TTS when Deepgram is unavailable
- Audio caching to avoid re-generating the same content
Always know what's breaking on Economic Times
- Real-time trending stories scraped from ET homepage with images
- Location-based local news using geolocation
- One-click analysis of any trending story (fetches article directly, skips search)
- 5-minute intelligent cache for performance
Secure, personalized experience with Supabase
- Email/password signup and login via modal overlays
- Domain preference selection during signup (12 news categories)
- Protected analyze/chat endpoints with JWT verification
- Personalized time-based greetings on the landing page
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β React Frontend β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββ β
β β Landing β β Briefing β β Deep β β Q&A β β
β β Page β β Panel β β Dive β β Dock β β
β ββββββ¬βββ¬βββ ββββββ¬ββββββ ββββββ¬ββββββ ββββ¬ββββ β
β β β β β β β
β β β ββββββββ΄βββββββββββββββ΄βββββββββββββ β
β β β β API Layer (api.ts + authHeaders) β
β β βββββ€ β
β β β βββββββββββββββββββββββ β
β β β β Supabase Auth β β
β β β β (AuthContext.tsx) β β
β ββββββββ€ βββββββββββββββββββββββ β
ββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββ
β HTTP + SSE
ββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββ
β β FastAPI Backend β
β βββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββ β
β β REST API (main.py) β β
β β /analyze-stream /chat /deep-dive /foryou /trending β β
β β (SSE progress) (auth) (auth) (auth) (public) β β
β ββββββ¬βββββββββββββββ¬βββββββ¬ββββββββββββ¬ββββββββββ¬ββββββββββ β
β β β β β β β
β ββββββΌβββββ βββββββΌββββ β ββββββΌβββββββ β β
β β RAG β β AI β β β Trending β β β
β β Engine β β Engine β β β + ForYou β β β
β β (FAISS) β β (GPT-4o)β β β Scraper β β β
β ββββββ¬βββββ ββββββ¬βββββ β βββββββββββββ β β
β β β β β β
β ββββββΌβββββββββββββββΌβββ β ββββββββββββββββββββΌβββββββββ β
β β OpenAI Embeddings β β β ET News Scraper β β
β β (text-embedding-3- β β β (JSON-LD + HTML) β β
β β small) + FAISS β β β + Semantic Rank β β
β ββββββββββββββββββββββββ β βββββββββββββββββββββββββββββ β
β β β
β ββββββββββΌβββββββββββ β
β β Supabase Auth β β
β β Verify (auth.py) β β
β ββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
User Query
β
ββββΊ ET Search (parallel queries) βββΊ Extract Article URLs
β β
β βββββββΌβββββββ
β β Fetch each β (concurrent, up to 10)
β β article β
β β via JSON-LDβ
β βββββββ¬βββββββ
β β
β βββββββββββββΌββββββββββββ
β β RAG Pipeline β
β β 1. Chunk (250 words) β
β β 2. Embed (OpenAI) β
β β 3. FAISS Index β
β β 4. Retrieve top-k β
β βββββββββββββ¬βββββββββββββ
β β
β Top-k chunks (~4K tokens)
β β
ββββΊ SSE Progress Events βββββββββββββββββββ€
β β
ββββΊ OpenAI GPT-4o-mini βββββββββββββββββββ
β β
β Structured Briefing
β + Session stored (with FAISS index)
β β
ββββΊ Frontend renders dashboard
| Requirement | Version |
|---|---|
| Python | 3.10+ |
| Node.js | 16+ |
| OpenAI API Key | Required |
| Supabase Project | Required (auth + profiles) |
| Deepgram API Key | Optional (voice input + TTS) |
git clone https://github.com/k-Rohit/EditoriAl.git
cd EditoriAl- Create a project at supabase.com
- Go to SQL Editor and run the migration:
-- Create profiles table
create table if not exists public.profiles (
id uuid references auth.users on delete cascade primary key,
email text not null default '',
full_name text not null default '',
preferred_domains text[] not null default '{}',
created_at timestamptz not null default now()
);
alter table public.profiles enable row level security;
create policy "Users can view own profile" on public.profiles for select using (auth.uid() = id);
create policy "Users can update own profile" on public.profiles for update using (auth.uid() = id);
create policy "Users can insert own profile" on public.profiles for insert with check (auth.uid() = id);
-- Auto-create profile on signup
create or replace function public.handle_new_user()
returns trigger as $$
declare
domains text[];
begin
select coalesce(
array(select jsonb_array_elements_text(new.raw_user_meta_data->'preferred_domains')),
'{}'
) into domains;
insert into public.profiles (id, email, full_name, preferred_domains)
values (new.id, new.email, coalesce(new.raw_user_meta_data->>'full_name', ''), domains)
on conflict (id) do update set
email = excluded.email, full_name = excluded.full_name, preferred_domains = excluded.preferred_domains;
return new;
end;
$$ language plpgsql security definer;
drop trigger if exists on_auth_user_created on auth.users;
create trigger on_auth_user_created
after insert on auth.users
for each row execute function public.handle_new_user();- Go to Authentication > Providers > Email and disable "Confirm email" (for hackathon)
cd backend
# Create virtual environment
python -m venv venv
source venv/bin/activate # macOS / Linux
# Install dependencies
pip install -r requirements.txt
# Configure environment
cp .env.example .env
# Edit .env and add:
# OPENAI_API_KEY = "sk-..."
# DEEPGRAM_API_KEY = "..." (optional)
# SUPABASE_URL = "https://xxx.supabase.co"
# SUPABASE_ANON_KEY = "eyJ..."
# Start server
python main.pyBackend runs at http://localhost:8000 API docs at http://localhost:8000/docs
cd frontend
# Install dependencies
npm install
# Configure environment
# Create .env.local with:
# VITE_API_BASE=http://localhost:8000
# VITE_SUPABASE_URL=https://xxx.supabase.co
# VITE_SUPABASE_ANON_KEY=eyJ...
# Start dev server
npm run devFrontend runs at http://localhost:8080
Root endpoint β returns service info and link to docs.
Health check β returns { "status": "ok" }.
SSE endpoint β streams progress events during analysis, then sends the final result.
Query params: ?query=RBI+monetary+policy and optionally &url=https://... to analyze a specific article directly.
SSE Events:
event: progress
data: {"step": "scraping", "message": "Searching Economic Times..."}
event: progress
data: {"step": "embedding", "message": "Reading & analyzing 9 articles..."}
event: progress
data: {"step": "generating", "message": "Generating intelligence briefing..."}
event: result
data: {"session_id": "uuid", "story": {...}, "articleCount": 9, "articleMeta": [...]}
Ask follow-up questions with per-question RAG retrieval.
Request:
{
"session_id": "uuid",
"question": "What did the RBI governor say about inflation?",
"chat_history": []
}Generate a full deep dive analysis for a session.
Request:
{ "session_id": "uuid" }Fetch personalized stories based on user's preferred domains.
Request:
{ "domains": ["tech", "markets", "startups"] }Fetch live trending stories from ET homepage with images.
Fetch location-based news from ET city editions.
Request:
{ "city": "Mumbai", "state": "Maharashtra" }Returns public configuration (Deepgram API key for client-side voice input).
| Technology | Purpose |
|---|---|
| FastAPI | Async REST API framework with SSE support |
| OpenAI GPT-4o-mini | Briefing generation, deep dive analysis & conversational Q&A |
| OpenAI Embeddings | Text embeddings via text-embedding-3-small (1536-dim) |
| FAISS | In-memory vector search for RAG retrieval |
| Supabase | Auth verification via JWT |
| httpx | Async HTTP client for web scraping |
| BeautifulSoup4 | HTML parsing & content extraction |
| sse-starlette | Server-Sent Events for streaming progress |
| Pydantic | Request/response validation |
| Uvicorn | High-performance ASGI server |
| Technology | Purpose |
|---|---|
| React 18 | UI framework |
| TypeScript | Type-safe development |
| Vite | Build tool & dev server |
| Tailwind CSS | Utility-first styling with custom dark design system |
| Supabase JS | Auth client (email/password, session management) |
| shadcn/ui | Radix-based component library |
| Deepgram | Real-time voice-to-text (STT) and text-to-speech (TTS) |
| Lucide | Icon library |
EditoriAl/
β
βββ backend/
β βββ main.py # FastAPI app, REST + SSE endpoints, auth middleware
β βββ ai_engine.py # OpenAI briefing (RAG-aware), deep dive & chat logic
β βββ rag_engine.py # RAG pipeline: chunk, embed (OpenAI), FAISS index, retrieve
β βββ news_scraper.py # ET article scraping + semantic ranking
β βββ trending.py # Trending, local news, and For You scrapers
β βββ auth.py # Supabase JWT verification dependency
β βββ requirements.txt # Python dependencies
β βββ Procfile # Railway start command
β βββ nixpacks.toml # Railway build config
β βββ .env.example # Environment variable template
β
βββ frontend/
β βββ src/
β β βββ components/
β β β βββ LandingPage.tsx # Hero + search + trending + local + auth modal
β β β βββ AppDashboard.tsx # Dashboard layout (sidebar + briefing + Q&A)
β β β βββ AppSidebar.tsx # Navigation sidebar with trending/local lists
β β β βββ BriefingPanel.tsx # AI briefing view (facts, impact, timeline)
β β β βββ DeepDivePage.tsx # Full-page deep dive analysis
β β β βββ ForYouPage.tsx # Personalized news feed by domain
β β β βββ AuthModal.tsx # Login/signup modal overlay with domain picker
β β β βββ QADock.tsx # Voice/text Q&A chat panel
β β β βββ LoadingScreen.tsx # SSE-driven loading animation
β β βββ contexts/
β β β βββ AuthContext.tsx # Supabase auth state provider
β β βββ hooks/
β β β βββ useVoiceInput.ts # Deepgram WebSocket + Web Speech fallback
β β β βββ useTextToSpeech.ts # Deepgram Aura TTS + browser TTS fallback
β β βββ lib/
β β β βββ supabase.ts # Supabase client initialization
β β β βββ utils.ts # Utility functions
β β βββ services/
β β β βββ api.ts # API client with auth headers & SSE streaming
β β βββ pages/
β β βββ Index.tsx # Main page state machine
β βββ public/
β β βββ icon.png # App icon
β βββ vercel.json # Vercel SPA rewrite config
β βββ .env.local # Frontend env vars (not committed)
β βββ package.json
β
βββ railway.json # Railway monorepo config
βββ README.md
Instead of sending all article text directly to the LLM (~20K+ tokens), EditoriAI uses a Retrieval-Augmented Generation pipeline:
- Chunk β Each article split into ~250-word overlapping chunks with metadata
- Embed β All chunks encoded via OpenAI
text-embedding-3-small(1536-dim vectors) - Index β FAISS
IndexFlatIPfor cosine similarity search (instant for <200 chunks) - Retrieve β Top-k chunks most relevant to the query (~4K tokens vs ~20K+)
- Generate β GPT-4o-mini produces structured briefing from focused context
Result: ~60% fewer LLM input tokens, better relevance, and faster responses.
Article search results are ranked using embedding-based cosine similarity on titles (not keyword matching), with a recency boost (0-0.15 score) favoring articles published within the last 6 hours. Articles scoring below 50% of the top result are dropped.
Economic Times is a Next.js SPA. EditoriAI extracts article text from JSON-LD structured data (<script type="application/ld+json">) embedded in each page, which contains the full articleBody. Search queries run in parallel via asyncio.gather for 2-4x speedup.
- Primary: Deepgram Nova-2 β WebSocket-based real-time STT with high accuracy
- Fallback: Web Speech API β Browser-native speech recognition when Deepgram is unavailable
| Variable | Required | Description |
|---|---|---|
OPENAI_API_KEY |
Yes | OpenAI API key for GPT-4o-mini + embeddings |
SUPABASE_URL |
Yes | Supabase project URL |
SUPABASE_ANON_KEY |
Yes | Supabase anonymous/public key |
DEEPGRAM_API_KEY |
No | Deepgram API key for voice-to-text and TTS |
| Variable | Required | Description |
|---|---|---|
VITE_API_BASE |
Yes | Backend URL (http://localhost:8000 for local dev) |
VITE_SUPABASE_URL |
Yes | Supabase project URL |
VITE_SUPABASE_ANON_KEY |
Yes | Supabase anonymous/public key |
Built for the ET Hackathon
From breaking news to full narrative