InternAgent is an AI-powered communications engine built for the Internship Cell CET. It takes any internship URL or raw text, scrapes and parses the relevant details, and synthesizes them into ready-to-publish assets — an Instagram poster and a WhatsApp community caption — complete with a scannable QR code.
Built to solve a real workflow pain point: juggling multiple AI tools, copy-pasting between tabs, and formatting content from scratch every time a new internship drops.
- Dual Input Modes — Scrape directly from a URL or paste raw text manually (useful for bot-protected or JS-rendered pages)
- Intelligent Scraping — Uses
BeautifulSoupwith acloudscraperfallback for 403-blocked sites and an SSL fallback for misconfigured hosts - SSRF Protection — Validates and resolves hostnames before any request is made; blocks private/loopback/multicast IPs
- AI Synthesis — Llama 3.1 70B (via NVIDIA NIM) condenses raw scraped content into structured poster copy and a WhatsApp caption
- Deterministic Splitting — Output is delimited by
===SPLIT===, parsed client-side into two distinct result panels - QR Code Generation — Auto-generates a scannable QR for the application URL using
qrcode.react - Rate Limiting — Flask-Limiter enforces 5 requests/minute and 20 requests/hour per IP
- Decoupled Architecture — Static frontend on GitHub Pages, Flask backend on Render; API keys never touch the client
| Layer | Stack |
|---|---|
| Frontend | React 19, Vite 8, Tailwind CSS, Framer Motion, @shadergradient/react, qrcode.react |
| Backend | Python, Flask, Flask-CORS, Flask-Limiter, BeautifulSoup4, cloudscraper, Requests |
| AI | NVIDIA NIM — meta/llama-3.1-70b-instruct via OpenAI-compatible SDK |
| Deployment | GitHub Pages (frontend) + Render w/ Gunicorn (backend) |
Prerequisites: Python 3.10+, Node.js 20+
git clone https://github.com/aswin-m-kumar/Intern_Agent.git
cd Intern_Agentpython -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtCreate a .env file at the project root:
NVIDIA_API_KEY=your_api_key_hereRun the backend:
python app.pyBackend will be available at http://127.0.0.1:5000.
cd frontend
npm install
npm run devThe frontend auto-detects localhost and routes API calls to http://127.0.0.1:5000 in development.
The included GitHub Actions workflow (.github/workflows/deploy.yml) handles CI/CD automatically on every push to main. It builds the Vite app and deploys frontend/dist to GitHub Pages.
Note:
vite.config.jssetsbase: '/Intern_Agent/'to match the repo name — update this if you fork under a different name.
Deploy as a Web Service on Render with the start command:
gunicorn app:appGunicorn is pre-configured via gunicorn.conf.py with a 120-second timeout (necessary for LLM generation latency) and 2 workers.
Set NVIDIA_API_KEY as an environment variable in your Render service dashboard.
Point the frontend to your Render URL by setting a VITE_API_URL environment variable during the GitHub Actions build, or update the fallback URL directly in InternAgentForm.jsx.
Intern_Agent/
├── app.py # Flask app, CORS, rate limiting, /api/generate endpoint
├── internship_agent.py # Scraping logic + NVIDIA NIM AI call
├── gunicorn.conf.py # Gunicorn worker/timeout config
├── requirements.txt
├── .env # (gitignored) NVIDIA_API_KEY
└── frontend/
├── src/
│ ├── App.jsx # Root layout, ShaderGradient background
│ ├── components/
│ │ ├── InternAgentForm.jsx # Main form, state, API call, result panels
│ │ └── LiquidGlassCard.jsx # Glassmorphism card component
│ ├── lib/utils.js # clsx + tailwind-merge helper
│ └── index.css # Tailwind + custom scrollbar
├── vite.config.js
└── tailwind.config.js
- User submits a URL or pastes raw text
- Backend validates the URL (scheme, length, SSRF check via DNS resolution)
- Page is fetched — with
cloudscraperfallback on 403, SSL fallback on cert errors BeautifulSoupstrips scripts/styles/nav and extracts up to 20,000 characters of readable text- Text is sent to Llama 3.1 70B with a structured prompt instructing it to output poster content and a WhatsApp caption separated by
===SPLIT=== - Frontend splits the response, renders both panels, and generates a QR code for the application URL