From dac96c270c2953d02bc986cf5cd949026a34e4e4 Mon Sep 17 00:00:00 2001 From: EternalKnight002 Date: Fri, 20 Mar 2026 14:55:56 +0530 Subject: [PATCH 1/2] feat: add Research Paper Explainer & Quiz Agent --- kits/research-paper-explainer/.env.example | 12 + kits/research-paper-explainer/.gitignore | 35 + kits/research-paper-explainer/README.md | 155 + .../app/api/explain/route.ts | 48 + .../app/api/quiz/route.ts | 69 + kits/research-paper-explainer/app/globals.css | 91 + kits/research-paper-explainer/app/layout.tsx | 27 + kits/research-paper-explainer/app/page.tsx | 427 + .../lamatic-config.json | 68 + kits/research-paper-explainer/next.config.mjs | 3 + .../package-lock.json | 7573 +++++++++++++++++ kits/research-paper-explainer/package.json | 29 + .../postcss.config.mjs | 7 + .../tailwind.config.ts | 14 + kits/research-paper-explainer/tsconfig.json | 20 + 15 files changed, 8578 insertions(+) create mode 100644 kits/research-paper-explainer/.env.example create mode 100644 kits/research-paper-explainer/.gitignore create mode 100644 kits/research-paper-explainer/README.md create mode 100644 kits/research-paper-explainer/app/api/explain/route.ts create mode 100644 kits/research-paper-explainer/app/api/quiz/route.ts create mode 100644 kits/research-paper-explainer/app/globals.css create mode 100644 kits/research-paper-explainer/app/layout.tsx create mode 100644 kits/research-paper-explainer/app/page.tsx create mode 100644 kits/research-paper-explainer/lamatic-config.json create mode 100644 kits/research-paper-explainer/next.config.mjs create mode 100644 kits/research-paper-explainer/package-lock.json create mode 100644 kits/research-paper-explainer/package.json create mode 100644 kits/research-paper-explainer/postcss.config.mjs create mode 100644 kits/research-paper-explainer/tailwind.config.ts create mode 100644 kits/research-paper-explainer/tsconfig.json diff --git a/kits/research-paper-explainer/.env.example b/kits/research-paper-explainer/.env.example new file mode 100644 index 00000000..352e803c --- /dev/null +++ b/kits/research-paper-explainer/.env.example @@ -0,0 +1,12 @@ +# Lamatic.ai Configuration +# Get these from https://studio.lamatic.ai β†’ your project settings + +LAMATIC_API_KEY=your_lamatic_api_key_here +LAMATIC_PROJECT_ID=your_project_id_here + +# Flow endpoint URLs (from your Lamatic Studio deployment) +EXPLAIN_FLOW_URL=https://your-project.lamatic.app/api/explain +QUIZ_FLOW_URL=https://your-project.lamatic.app/api/quiz + +# Optional: Customize the app title +NEXT_PUBLIC_APP_TITLE=Research Paper Explainer diff --git a/kits/research-paper-explainer/.gitignore b/kits/research-paper-explainer/.gitignore new file mode 100644 index 00000000..6a936543 --- /dev/null +++ b/kits/research-paper-explainer/.gitignore @@ -0,0 +1,35 @@ +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/kits/research-paper-explainer/README.md b/kits/research-paper-explainer/README.md new file mode 100644 index 00000000..63c84b69 --- /dev/null +++ b/kits/research-paper-explainer/README.md @@ -0,0 +1,155 @@ +# πŸ“š Research Paper Explainer & Quiz Agent + +> A Next.js kit built on [Lamatic AgentKit](https://github.com/Lamatic/AgentKit) that takes any research paper abstract or full text, explains it at your chosen comprehension level, and generates an interactive multiple-choice quiz to test understanding. + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Mortarion002/AgentKit/tree/main/apps/research-paper-explainer) + +--- + +## 🧠 Problem Statement + +Reading academic research papers is hard. Dense jargon, complex methodologies, and assumed domain knowledge make papers inaccessible to students, curious learners, and even professionals stepping outside their niche. + +**PaperLens** solves this with two AI-powered agents: +1. **Explainer Agent** β€” Breaks down a paper into plain language at high-school, undergraduate, or expert level, structured around: Core Problem β†’ Methodology β†’ Key Findings β†’ Real-World Impact. +2. **Quiz Agent** β€” Generates a custom multiple-choice quiz from the paper to reinforce learning and test comprehension. + +--- + +## ✨ Features + +- πŸ“„ Paste any research paper abstract or full text +- πŸŽ“ Choose explanation level: Simple / Intermediate / Expert +- 🧩 Generate 3–10 quiz questions with answer feedback & explanations +- πŸ“Š Live score tracking after quiz submission +- ⚑ Two independent Lamatic Flows (explain + quiz) +- 🎨 Clean, distraction-free editorial UI + +--- + +## πŸ—‚ Folder Structure + +``` +research-paper-explainer/ +β”œβ”€β”€ app/ +β”‚ β”œβ”€β”€ page.tsx # Main UI (input + output panels) +β”‚ β”œβ”€β”€ layout.tsx # Root layout with fonts +β”‚ β”œβ”€β”€ globals.css # Design system & animations +β”‚ └── api/ +β”‚ β”œβ”€β”€ explain/route.ts # Calls the Lamatic explain flow +β”‚ └── quiz/route.ts # Calls the Lamatic quiz flow +β”œβ”€β”€ lamatic-config.json # Flow definitions for Lamatic Studio +β”œβ”€β”€ .env.example # Required environment variables +β”œβ”€β”€ package.json +β”œβ”€β”€ tailwind.config.ts +β”œβ”€β”€ tsconfig.json +└── README.md +``` + +--- + +## πŸš€ Getting Started + +### 1. Clone the Repository + +```bash +git clone https://github.com/Lamatic/AgentKit.git +cd AgentKit/kits/research-paper-explainer +``` + +### 2. Install Dependencies + +```bash +npm install +``` + +### 3. Set Up Lamatic Flows + +1. Sign up at [lamatic.ai](https://lamatic.ai) and create a new project +2. In Lamatic Studio, create **two flows** using the definitions in `lamatic-config.json`: + - **Explain Flow** β€” accepts `paperContent` + `level`, returns a markdown explanation + - **Quiz Flow** β€” accepts `paperContent` + `numQuestions`, returns a JSON quiz +3. Deploy both flows and copy their endpoint URLs + +### 4. Configure Environment Variables + +```bash +cp .env.example .env +``` + +Edit `.env` and fill in: + +```env +LAMATIC_API_KEY=your_lamatic_api_key +LAMATIC_PROJECT_ID=your_project_id +EXPLAIN_FLOW_URL=https://your-project.lamatic.app/api/explain +QUIZ_FLOW_URL=https://your-project.lamatic.app/api/quiz +``` + +### 5. Run Locally + +```bash +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) + +--- + +## 🌐 Deploy to Vercel + +```bash +npm run build +vercel --prod +``` + +Or use the one-click deploy button at the top of this README. + +--- + +## πŸ”§ Lamatic Flow Configuration + +The `lamatic-config.json` defines both flows. Key configuration: + +| Flow | Input Fields | Output | +|---|---|---| +| `explain-flow` | `paperContent`, `level` | Markdown explanation string | +| `quiz-flow` | `paperContent`, `numQuestions` | JSON: `{ questions: [...] }` | + +**Quiz JSON shape expected from Lamatic:** + +```json +{ + "questions": [ + { + "question": "What problem does this paper solve?", + "options": ["A) ...", "B) ...", "C) ...", "D) ..."], + "correct": 0, + "explanation": "The paper focuses on..." + } + ] +} +``` + +--- + +## πŸ›  Tech Stack + +| Layer | Tech | +|---|---| +| Frontend | Next.js 14, TypeScript, Tailwind CSS | +| AI Agent | Lamatic Flow (GPT-4o-mini via Lamatic Studio) | +| Markdown Rendering | `react-markdown` + `remark-gfm` | +| Deployment | Vercel | + +--- + +## 🀝 Contributing + +Found a bug or want to improve this kit? Open an issue or PR on the [AgentKit repository](https://github.com/Lamatic/AgentKit). + +--- + +## πŸ“„ License + +MIT β€” Built by [Aman Kumar](https://github.com/Mortarion002) as part of the Lamatic AgentKit community. diff --git a/kits/research-paper-explainer/app/api/explain/route.ts b/kits/research-paper-explainer/app/api/explain/route.ts new file mode 100644 index 00000000..75c6f8dc --- /dev/null +++ b/kits/research-paper-explainer/app/api/explain/route.ts @@ -0,0 +1,48 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + try { + const { paperContent, level } = await req.json(); + + if (!paperContent || paperContent.trim().length < 50) { + return NextResponse.json( + { error: "Please provide a research paper abstract or content (at least 50 characters)." }, + { status: 400 } + ); + } + + const flowUrl = process.env.EXPLAIN_FLOW_URL; + const apiKey = process.env.LAMATIC_API_KEY; + + if (!flowUrl || !apiKey) { + return NextResponse.json( + { error: "Server misconfiguration: missing EXPLAIN_FLOW_URL or LAMATIC_API_KEY." }, + { status: 500 } + ); + } + + const response = await fetch(flowUrl, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${apiKey}`, + }, + body: JSON.stringify({ paperContent, level: level || "undergraduate" }), + }); + + if (!response.ok) { + const errText = await response.text(); + console.error("Lamatic explain flow error:", errText); + return NextResponse.json( + { error: "The AI agent failed to process the request. Please try again." }, + { status: 502 } + ); + } + + const data = await response.json(); + return NextResponse.json({ explanation: data?.result || data?.output || data }); + } catch (err) { + console.error("Explain API error:", err); + return NextResponse.json({ error: "Internal server error." }, { status: 500 }); + } +} diff --git a/kits/research-paper-explainer/app/api/quiz/route.ts b/kits/research-paper-explainer/app/api/quiz/route.ts new file mode 100644 index 00000000..8970c6ff --- /dev/null +++ b/kits/research-paper-explainer/app/api/quiz/route.ts @@ -0,0 +1,69 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + try { + const { paperContent, numQuestions } = await req.json(); + + if (!paperContent || paperContent.trim().length < 50) { + return NextResponse.json( + { error: "Please provide paper content before generating a quiz." }, + { status: 400 } + ); + } + + const flowUrl = process.env.QUIZ_FLOW_URL; + const apiKey = process.env.LAMATIC_API_KEY; + + if (!flowUrl || !apiKey) { + return NextResponse.json( + { error: "Server misconfiguration: missing QUIZ_FLOW_URL or LAMATIC_API_KEY." }, + { status: 500 } + ); + } + + const response = await fetch(flowUrl, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${apiKey}`, + }, + body: JSON.stringify({ + paperContent, + numQuestions: numQuestions || 5, + }), + }); + + if (!response.ok) { + const errText = await response.text(); + console.error("Lamatic quiz flow error:", errText); + return NextResponse.json( + { error: "The AI agent failed to generate the quiz. Please try again." }, + { status: 502 } + ); + } + + const data = await response.json(); + const raw = data?.result || data?.output || data; + + // Parse if the LLM returned a JSON string + let parsed: { questions: QuizQuestion[] }; + if (typeof raw === "string") { + const match = raw.match(/\{[\s\S]*\}/); + parsed = JSON.parse(match ? match[0] : raw); + } else { + parsed = raw; + } + + return NextResponse.json(parsed); + } catch (err) { + console.error("Quiz API error:", err); + return NextResponse.json({ error: "Internal server error." }, { status: 500 }); + } +} + +interface QuizQuestion { + question: string; + options: string[]; + correct: number; + explanation: string; +} diff --git a/kits/research-paper-explainer/app/globals.css b/kits/research-paper-explainer/app/globals.css new file mode 100644 index 00000000..95ef3b1b --- /dev/null +++ b/kits/research-paper-explainer/app/globals.css @@ -0,0 +1,91 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --ink: #1a1207; + --paper: #f5f0e8; + --cream: #ede7d3; + --amber: #c8860a; + --amber-light: #f0a830; + --amber-pale: #fdf3dc; + --muted: #7a6e5f; + --border: #d6cdb8; + --success: #2d6a4f; + --error: #9b2226; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + background-color: var(--paper); + color: var(--ink); + font-family: 'DM Sans', sans-serif; + min-height: 100vh; +} + +.font-serif { + font-family: 'Instrument Serif', serif; +} + +.font-mono { + font-family: 'DM Mono', monospace; +} + +/* Scrollbar */ +::-webkit-scrollbar { width: 6px; } +::-webkit-scrollbar-track { background: var(--cream); } +::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; } + +/* Prose styles for markdown */ +.prose h1, .prose h2, .prose h3 { + font-family: 'Instrument Serif', serif; + color: var(--ink); + margin-top: 1.5em; + margin-bottom: 0.5em; +} +.prose h2 { font-size: 1.25rem; } +.prose h3 { font-size: 1.1rem; } +.prose p { margin-bottom: 0.85em; line-height: 1.75; color: #2e2416; } +.prose strong { color: var(--ink); font-weight: 600; } +.prose ul { padding-left: 1.5em; margin-bottom: 0.85em; } +.prose ul li { margin-bottom: 0.35em; } +.prose ol { padding-left: 1.5em; margin-bottom: 0.85em; } +.prose ol li { margin-bottom: 0.35em; } + +/* Animations */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(12px); } + to { opacity: 1; transform: translateY(0); } +} +@keyframes shimmer { + 0% { background-position: -200% 0; } + 100% { background-position: 200% 0; } +} +@keyframes pulse-dot { + 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; } + 40% { transform: scale(1); opacity: 1; } +} + +.animate-fade-in { + animation: fadeIn 0.45s ease-out forwards; +} +.animate-fade-in-delay { + animation: fadeIn 0.45s ease-out 0.15s forwards; + opacity: 0; +} + +.loading-dot { + display: inline-block; + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--amber); + animation: pulse-dot 1.4s ease-in-out infinite; +} +.loading-dot:nth-child(2) { animation-delay: 0.2s; } +.loading-dot:nth-child(3) { animation-delay: 0.4s; } diff --git a/kits/research-paper-explainer/app/layout.tsx b/kits/research-paper-explainer/app/layout.tsx new file mode 100644 index 00000000..794dc00e --- /dev/null +++ b/kits/research-paper-explainer/app/layout.tsx @@ -0,0 +1,27 @@ +import type { Metadata } from "next"; +import "./globals.css"; + +export const metadata: Metadata = { + title: process.env.NEXT_PUBLIC_APP_TITLE || "Research Paper Explainer", + description: "AI-powered research paper explainer and quiz generator built on Lamatic AgentKit", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + + + + + {children} + + ); +} diff --git a/kits/research-paper-explainer/app/page.tsx b/kits/research-paper-explainer/app/page.tsx new file mode 100644 index 00000000..cc753aa8 --- /dev/null +++ b/kits/research-paper-explainer/app/page.tsx @@ -0,0 +1,427 @@ +"use client"; + +import { useState } from "react"; +import ReactMarkdown from "react-markdown"; +import remarkGfm from "remark-gfm"; + +type Level = "high-school" | "undergraduate" | "expert"; +type Tab = "explain" | "quiz"; + +interface QuizQuestion { + question: string; + options: string[]; + correct: number; + explanation: string; +} + +interface QuizState { + questions: QuizQuestion[]; + answers: (number | null)[]; + submitted: boolean; +} + +const LEVELS: { value: Level; label: string; desc: string }[] = [ + { value: "high-school", label: "Simple", desc: "High school level" }, + { value: "undergraduate", label: "Intermediate", desc: "Undergrad level" }, + { value: "expert", label: "Expert", desc: "Domain specialist" }, +]; + +export default function HomePage() { + const [paperContent, setPaperContent] = useState(""); + const [level, setLevel] = useState("undergraduate"); + const [tab, setTab] = useState("explain"); + const [numQuestions, setNumQuestions] = useState(5); + + const [explanation, setExplanation] = useState(null); + const [quiz, setQuiz] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + async function handleExplain() { + if (!paperContent.trim()) return; + setLoading(true); + setError(null); + setExplanation(null); + try { + const res = await fetch("/api/explain", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ paperContent, level }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Something went wrong."); + setExplanation(typeof data.explanation === "string" ? data.explanation : JSON.stringify(data.explanation, null, 2)); + setTab("explain"); + } catch (e: unknown) { + setError(e instanceof Error ? e.message : "Unknown error"); + } finally { + setLoading(false); + } + } + + async function handleQuiz() { + if (!paperContent.trim()) return; + setLoading(true); + setError(null); + setQuiz(null); + try { + const res = await fetch("/api/quiz", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ paperContent, numQuestions }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Something went wrong."); + setQuiz({ + questions: data.questions, + answers: new Array(data.questions.length).fill(null), + submitted: false, + }); + setTab("quiz"); + } catch (e: unknown) { + setError(e instanceof Error ? e.message : "Unknown error"); + } finally { + setLoading(false); + } + } + + function handleAnswer(qIdx: number, optIdx: number) { + if (!quiz || quiz.submitted) return; + setQuiz((prev) => { + if (!prev) return prev; + const answers = [...prev.answers]; + answers[qIdx] = optIdx; + return { ...prev, answers }; + }); + } + + function handleSubmitQuiz() { + setQuiz((prev) => prev ? { ...prev, submitted: true } : prev); + } + + const score = quiz?.submitted + ? quiz.questions.filter((q, i) => quiz.answers[i] === q.correct).length + : null; + + return ( +
+ {/* Header */} +
+
+
+

+ PaperLens +

+

+ Research Paper Explainer & Quiz Β· Lamatic AgentKit +

+
+
+ ✦ AI-Powered +
+
+
+ +
+
+ {/* LEFT PANEL β€” Input */} +
+
+ +