feat: Add research-paper-analyzer kit#163
Conversation
Adds kit metadata (lamatic.config.js), agent identity (agent.md), README with setup guide, safety constitution, and .gitignore. Uses plain JavaScript — no TypeScript — matching contributor's stack. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Defines the 4-node Lamatic flow (API Trigger → Extract From File → LLM Node → API Response) with full node/edge config and the structured prompt that produces title, authors, year, problem statement, methodology, findings, limitations, plain-English summary, and follow-up questions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- orchestrate.js: maps flow ID from env to Lamatic workflow - lib/lamatic-client.js: initialises Lamatic SDK, validates env vars - actions/orchestrate.js: server action that calls executeFlow() and returns structured analysis or a typed error - package.json, jsconfig.json, next.config.mjs, tailwind + postcss configs: plain JS/JSX project setup (no TypeScript) - .env.example: documents required env vars Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
page.jsx (JSX, no TypeScript): - URL input form with loading state - Displays title, authors, year in a header bar - Plain English Summary always expanded (highlighted) - Problem statement, methodology, findings, limitations, follow-up questions all collapsible independently - Copy-to-JSON and New-paper reset buttons - Error state with icon layout.jsx + globals.css: Next.js App Router shell with Tailwind Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Next.js server actions, lamatic-client.js, next.config, tailwind/postcss configs, and App Router structure are all removed. The new backend will be FastAPI (Python) matching the contributor's stack, with a plain React + Vite frontend. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- main.py: POST /analyze accepts pdf_url, calls Lamatic flow via httpx, returns structured JSON; GET /health for readiness check - CORS configured for localhost:5173 (Vite) and localhost:3000 - Pydantic request model validates input - Typed error handling: 401, 404, 504 timeout, network errors - requirements.txt: fastapi, uvicorn, httpx, python-dotenv, pydantic - .env.example: documents all 4 required env vars Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- src/App.jsx: fetches POST /analyze from FastAPI backend; shows title/authors/year bar, Plain English Summary (always open), and collapsible sections for problem statement, methodology, key findings, limitations, follow-up questions - Copy-to-JSON and New-paper reset buttons - Error handling with icon display - vite.config.js: proxies /analyze and /health to localhost:8000 so no CORS issues in dev - VITE_BACKEND_URL env var for production deploys - Tailwind CSS for styling Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Adds architecture diagram: React → FastAPI → Lamatic → LLM - Separate startup instructions for backend (uvicorn) and frontend (vite) - Documents POST /analyze request/response schema - Updates tech stack section: FastAPI, Python, Vite (no Next.js) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Lamatic exposes a single GraphQL endpoint per project, not REST. Updated main.py to send the ExecuteWorkflow query with workflowId and payload variables. Also handles GraphQL-level errors from data.errors and checks execute_result.status == "success". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThis PR adds a Research Paper Analyzer kit: a Lamatic flow that extracts PDF text and returns structured JSON analysis, a Next.js frontend (Analyzer UI), a server action that executes the Lamatic flow, prompts/constitution files, README, and repo config. ChangesResearch Paper Analyzer Kit
Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new “Research Paper Analyzer” kit that extracts text from a PDF URL and returns a structured academic analysis via a Lamatic flow, with a bundled FastAPI backend and React/Vite frontend.
Changes:
- Introduces Lamatic flow + prompts/constitution for extracting and analyzing academic PDFs into structured JSON
- Adds a FastAPI service that calls Lamatic GraphQL to execute the flow
- Adds a React + Vite + Tailwind frontend UI to submit a PDF URL and render/copy results
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| kits/research-paper-analyzer/flows/research-paper-analyzer.js | Defines the Lamatic flow nodes, prompt wiring, and output schema for the analyzer |
| kits/research-paper-analyzer/prompts/analyze-paper.md | Adds the user prompt that requests a strict JSON breakdown of the paper |
| kits/research-paper-analyzer/constitutions/default.md | Adds safety/accuracy guardrails and an error behavior for non-paper input |
| kits/research-paper-analyzer/apps/backend/main.py | Implements a FastAPI proxy that executes the Lamatic workflow via GraphQL |
| kits/research-paper-analyzer/apps/frontend/src/App.jsx | Implements the UI + request handling and renders the structured analysis |
| kits/research-paper-analyzer/apps/frontend/package.json | Adds frontend dependencies/devDependencies for Vite/React/Tailwind |
| kits/research-paper-analyzer/README.md | Documents setup, architecture, and usage for the new kit |
| kits/research-paper-analyzer/agent.md | Documents agent identity, capabilities, and intended output schema |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| year: { type: ["number", "null"] }, | ||
| problem_statement: { type: "string" }, | ||
| methodology: { type: "string" }, | ||
| key_findings: { type: "array", items: { type: "string" } }, | ||
| limitations: { type: "array", items: { type: "string" } }, | ||
| plain_english_summary: { type: "string" }, | ||
| follow_up_questions: { type: "array", items: { type: "string" } }, | ||
| }, | ||
| required: [ | ||
| "title", "authors", "year", "problem_statement", "methodology", | ||
| "key_findings", "limitations", "plain_english_summary", "follow_up_questions", | ||
| ], |
| ## Accuracy | ||
| - Only draw conclusions directly supported by the paper's content | ||
| - Clearly flag when a section is missing, ambiguous, or truncated | ||
| - If the input is not an academic paper, return: `{"error": "Not an academic paper"}` |
| app.add_middleware( | ||
| CORSMiddleware, | ||
| allow_origins=["http://localhost:5173", "http://localhost:3000"], | ||
| allow_methods=["POST", "GET"], | ||
| allow_headers=["*"], | ||
| ) |
| const BACKEND_URL = import.meta.env.VITE_BACKEND_URL || ""; | ||
|
|
||
| async function callAnalyze(pdfUrl) { | ||
| const res = await fetch(`${BACKEND_URL}/analyze`, { |
| - **Extract From File** — file URL: `{{trigger.pdf_url}}` | ||
| - **LLM Node** — use prompt from `prompts/analyze-paper.md`, structured JSON output | ||
| - **API Response** — output: `{{LLMNode.output}}` |
| - Format all output as structured JSON matching the defined schema | ||
|
|
||
| ## Output Schema | ||
|
|
Adds a Pydantic field_validator on AnalyzeRequest.pdf_url that: - Rejects any non-HTTPS scheme (file://, http://, gopher://, etc.) - Rejects raw IP addresses in private/reserved ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, 169.254.0.0/16 (cloud IMDS), 0.0.0.0/8, ::1/128, fc00::/7 Without this, an attacker could supply an internal URL and have Lamatic's servers fetch it, leaking cloud metadata or internal service responses back in the API response. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
/validate |
|
📡 Running Studio validation — results will appear here shortly. |
Studio Runtime Validation (Phase 2)❌ Studio validation failed. The kit was rejected by Lamatic Studio. Errorsresearch-paper-analyzer
Please fix the errors above and push a new commit to re-run validation. |
|
Hello @Suhas-123-cell Please address the changes mentioned by the github action above. |
- Rename lamatic.config.js → lamatic.config.ts with `export default` syntax
- Rename flows/research-paper-analyzer.js → .ts with proper Lamatic Studio
node format (triggerNode/dynamicNode, data.nodeId, data.values pattern)
- Add required `export default { meta, inputs, references, nodes, edges }`
- Fixes "flows array must not be empty" Studio validation error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
kits/research-paper-analyzer/apps/backend/.gitignore (1)
1-8:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMission critical: add
.env.localto ignore list before launch.Your secrets shield is only half deployed:
.envis ignored, but.env.localis not. That leaves a common local credential file exposable to accidental commits.🔧 Suggested patch
.env +.env.local __pycache__/ *.py[cod] *.pyo .venv/ venv/ env/As per coding guidelines: “The
.gitignorefile must exclude.envand.env.localto prevent accidental secret commits.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/research-paper-analyzer/apps/backend/.gitignore` around lines 1 - 8, The .gitignore currently ignores .env but not .env.local; update the repository ignore list by adding the entry ".env.local" (alongside the existing ".env") to the .gitignore so local credential files are not committed; locate the .gitignore used in the backend app (the file shown contains entries like ".env", "__pycache__/", ".venv/") and append ".env.local" as a new line to ensure both .env and .env.local are excluded from commits.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@kits/research-paper-analyzer/apps/backend/main.py`:
- Around line 52-69: The validate_pdf_url validator currently only blocks
literal IP hostnames; update validate_pdf_url to (1) explicitly reject
localhost-style hostnames (e.g., "localhost", any hostname ending with
".localhost") immediately, and (2) perform DNS resolution for the parsed
hostname to obtain all A/AAAA addresses (e.g., via socket.getaddrinfo or an
equivalent resolver) and check each resolved ip against _BLOCKED_RANGES using
ipaddress.ip_address; if any resolved address falls inside a blocked range raise
ValueError("URL resolves to a private or reserved address."); keep the existing
HTTPS scheme check and the hostname-empty check intact.
In `@kits/research-paper-analyzer/apps/frontend/package.json`:
- Around line 11-22: The package.json dependencies and devDependencies currently
use caret ranges (e.g., "react": "^18.3.1", "vite": "^5.3.1"); change every
version string that starts with a caret to the exact version without the caret
(e.g., "react": "18.3.1", "vite": "5.3.1") so all entries under "dependencies"
and "devDependencies" are pinned; update the entries for lucide-react, react,
react-dom, `@vitejs/plugin-react`, autoprefixer, postcss, tailwindcss, and vite
accordingly to their exact x.y.z values.
- Line 20: Update the frontend kit to use Tailwind CSS v4+ by changing
devDependencies.tailwindcss in package.json from "^3.4.4" to a pinned v4+
version (e.g. "4.0.0" or the exact release you choose), then update
tailwind.config.js and the PostCSS config to the v4 config shape and plugin
usage, and modify apps/frontend/src/index.css to use any v4-compatible directive
or plugin imports if needed; also replace caret ranges in package.json
devDependencies with exact pinned versions to follow kit dependency pinning
guidelines.
In `@kits/research-paper-analyzer/apps/frontend/postcss.config.js`:
- Around line 2-4: The PostCSS plugin map currently uses the v3-style keys
(plugins object containing tailwindcss and autoprefixer); replace that plugin
map so it only registers the v4 plugin key "`@tailwindcss/postcss`" with an empty
config object and remove the separate "tailwindcss" and "autoprefixer" entries,
and then update the main CSS files to replace any v3 directives "`@tailwind`
base/components/utilities" with a single import directive '`@import`
"tailwindcss";' so the build uses Tailwind v4’s official PostCSS wiring.
In `@kits/research-paper-analyzer/apps/frontend/src/main.jsx`:
- Around line 1-10: The project entry uses JSX files (main.jsx importing
App.jsx) and index.html still references /src/main.jsx which violates the kit
policy requiring TypeScript; rename main.jsx → main.tsx and App.jsx → App.tsx,
update the import in main (change import "./App.jsx" to import "./App.tsx") and
update apps/frontend/index.html to load /src/main.tsx; finally add TypeScript
support by adding a tsconfig.json (basic React/JSX settings) and ensure
"typescript" is added as a devDependency so the renamed .ts/.tsx files compile.
In `@kits/research-paper-analyzer/flows/research-paper-analyzer.ts`:
- Around line 145-146: The outputMapping currently nests the LLM response under
an "analysis" key which changes the returned object shape; update outputMapping
so it returns LLMNode_1.output.generatedResponse at the top level (i.e., remove
the wrapping "analysis" object) so executeWorkflow.result is the analysis object
expected by the frontend. Ensure the mapping references
LLMNode_1.output.generatedResponse directly in outputMapping.
- Around line 109-133: The current outputSchema (the JSON.stringify passed to
outputSchema in research-paper-analyzer.ts) only allows the full analysis shape
and therefore rejects the documented non-paper fallback; modify that JSON schema
to include an explicit error variant (e.g., a oneOf with the existing object and
a second object with properties like status: {type:"string"}, error:
{type:"string"}, details: {type:"object", additionalProperties:true}) or change
the single response shape to include a status and optional error field (add
"status" and "error" to properties and make the original analysis properties
optional), and update the required array accordingly so the flow will accept the
documented error response from agent.md/constitutions/default.md.
In `@kits/research-paper-analyzer/lamatic.config.ts`:
- Around line 1-18: This kit config is in the wrong directory; move the entire
kit folder into the required pattern kits/<category>/<kit-name> (choose one of
the allowed categories: agentic, assistant, automation, embed) and update the
config's path-sensitive fields accordingly: adjust links.github and links.deploy
(root-directory query param) to reflect the new directory layout, and verify the
exported object (name "Research Paper Analyzer", steps array with id
"research-paper-analyzer", and envKey "RESEARCH_PAPER_ANALYZER_FLOW_ID") still
matches the relocated folder and any tooling that consumes it.
In `@kits/research-paper-analyzer/prompts/analyze-paper.md`:
- Around line 18-22: The prompt fallback rule ("use null for any missing
scalar") conflicts with the flow schema in flows/research-paper-analyzer.ts
which only permits year to be null; pick one contract and implement it: either
(A) update prompts/analyze-paper.md to remove the blanket "use null" rule and
state that only year may be null (ensuring title, problem_statement,
methodology, plain_english_summary must be present), or (B) update the
flow/schema/types in flows/research-paper-analyzer.ts to allow null for the
scalar fields title, problem_statement, methodology, and plain_english_summary
(make their types nullable and adjust validation). Reference the file
analyze-paper.md and the flow/research-paper-analyzer.ts fields (title,
problem_statement, methodology, plain_english_summary, year) when making the
change so prompt and schema agree.
In `@kits/research-paper-analyzer/README.md`:
- Around line 18-23: Several fenced code blocks in the README (e.g., the ASCII
diagram starting "React (Vite/JSX) → FastAPI (Python) → Lamatic Flow →
LLM", the `.env` block beginning with RESEARCH_PAPER_ANALYZER_FLOW_ID, and the
JSON examples used under "POST /analyze") are missing language tags (MD040) and
lack surrounding blank lines (MD031); update each fenced block to include the
appropriate language tag (e.g., ```text, ```env, ```json) and ensure there is a
blank line before and after every fenced block so the validator passes,
targeting the blocks that contain the ASCII diagram, the `.env` variables, and
the request/response JSON examples.
---
Outside diff comments:
In `@kits/research-paper-analyzer/apps/backend/.gitignore`:
- Around line 1-8: The .gitignore currently ignores .env but not .env.local;
update the repository ignore list by adding the entry ".env.local" (alongside
the existing ".env") to the .gitignore so local credential files are not
committed; locate the .gitignore used in the backend app (the file shown
contains entries like ".env", "__pycache__/", ".venv/") and append ".env.local"
as a new line to ensure both .env and .env.local are excluded from commits.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 917b2d18-a7f6-40c0-81a6-6ca2a55a0250
📒 Files selected for processing (21)
kits/research-paper-analyzer/.gitignorekits/research-paper-analyzer/README.mdkits/research-paper-analyzer/agent.mdkits/research-paper-analyzer/apps/backend/.env.examplekits/research-paper-analyzer/apps/backend/.gitignorekits/research-paper-analyzer/apps/backend/main.pykits/research-paper-analyzer/apps/backend/requirements.txtkits/research-paper-analyzer/apps/frontend/.env.examplekits/research-paper-analyzer/apps/frontend/.gitignorekits/research-paper-analyzer/apps/frontend/index.htmlkits/research-paper-analyzer/apps/frontend/package.jsonkits/research-paper-analyzer/apps/frontend/postcss.config.jskits/research-paper-analyzer/apps/frontend/src/App.jsxkits/research-paper-analyzer/apps/frontend/src/index.csskits/research-paper-analyzer/apps/frontend/src/main.jsxkits/research-paper-analyzer/apps/frontend/tailwind.config.jskits/research-paper-analyzer/apps/frontend/vite.config.jskits/research-paper-analyzer/constitutions/default.mdkits/research-paper-analyzer/flows/research-paper-analyzer.tskits/research-paper-analyzer/lamatic.config.tskits/research-paper-analyzer/prompts/analyze-paper.md
| @field_validator("pdf_url") | ||
| @classmethod | ||
| def validate_pdf_url(cls, v: str) -> str: | ||
| parsed = urlparse(v) | ||
| if parsed.scheme not in {"https"}: | ||
| raise ValueError("Only HTTPS URLs are accepted.") | ||
| hostname = parsed.hostname or "" | ||
| if not hostname: | ||
| raise ValueError("URL must contain a valid hostname.") | ||
| try: | ||
| ip = ipaddress.ip_address(hostname) | ||
| if any(ip in net for net in _BLOCKED_RANGES): | ||
| raise ValueError("URL resolves to a private or reserved address.") | ||
| except ValueError as exc: | ||
| if "private or reserved" in str(exc): | ||
| raise | ||
| # hostname is a domain name — pass through | ||
| return v |
There was a problem hiding this comment.
Mission-critical: the private-network guard is bypassable through hostnames.
This validator only rejects literal IP hosts. https://localhost/... and any public hostname that resolves to 127.0.0.1, RFC1918, or other blocked ranges hit the except ValueError path and are accepted, so the downstream extractor can still be pointed at internal resources. Resolve A/AAAA records and reject any blocked result, and explicitly deny localhost-style names.
🧰 Tools
🪛 Ruff (0.15.15)
[warning] 57-57: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 60-60: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 64-64: Abstract raise to an inner function
(TRY301)
[warning] 64-64: Avoid specifying long messages outside the exception class
(TRY003)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/backend/main.py` around lines 52 - 69, The
validate_pdf_url validator currently only blocks literal IP hostnames; update
validate_pdf_url to (1) explicitly reject localhost-style hostnames (e.g.,
"localhost", any hostname ending with ".localhost") immediately, and (2) perform
DNS resolution for the parsed hostname to obtain all A/AAAA addresses (e.g., via
socket.getaddrinfo or an equivalent resolver) and check each resolved ip against
_BLOCKED_RANGES using ipaddress.ip_address; if any resolved address falls inside
a blocked range raise ValueError("URL resolves to a private or reserved
address."); keep the existing HTTPS scheme check and the hostname-empty check
intact.
| "dependencies": { | ||
| "lucide-react": "^0.469.0", | ||
| "react": "^18.3.1", | ||
| "react-dom": "^18.3.1" | ||
| }, | ||
| "devDependencies": { | ||
| "@vitejs/plugin-react": "^4.3.1", | ||
| "autoprefixer": "^10.4.19", | ||
| "postcss": "^8.4.38", | ||
| "tailwindcss": "^3.4.4", | ||
| "vite": "^5.3.1" | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="kits/research-paper-analyzer/apps/frontend/package.json"
echo "== File =="
wc -l "$FILE"
echo
echo "== Relevant dependency block =="
# Print around dependencies/devDependencies
sed -n '1,120p' "$FILE" | nl -ba | sed -n '1,120p'
echo
echo "== Check for caret ranges in dependency sections =="
rg -n '"(dependencies|devDependencies)"\s*:' -S "$FILE"
echo
rg -n '\^' "$FILE" || trueRepository: Lamatic/AgentKit
Length of output: 225
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="kits/research-paper-analyzer/apps/frontend/package.json"
echo "== File =="
wc -l "$FILE"
echo
echo "== Show package.json =="
# Small file (23 lines); safe to print fully with line numbers via awk
awk '{print NR ":" $0}' "$FILE"
echo
echo "== Check dependency keys exist =="
rg -n '"dependencies"\s*:' "$FILE" || true
rg -n '"devDependencies"\s*:' "$FILE" || true
echo
echo "== Check for caret (^) semver ranges in the file =="
rg -n '\^' "$FILE" || trueRepository: Lamatic/AgentKit
Length of output: 1093
Mission brief: pin dependency versions.
In kits/research-paper-analyzer/apps/frontend/package.json (lines 11–22), both dependencies and devDependencies use caret semver ranges (e.g., ^18.3.1, ^5.3.1). Replace all ^x.y.z with exact x.y.z to comply with the kits/**/package.json pinned-version policy.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/frontend/package.json` around lines 11 -
22, The package.json dependencies and devDependencies currently use caret ranges
(e.g., "react": "^18.3.1", "vite": "^5.3.1"); change every version string that
starts with a caret to the exact version without the caret (e.g., "react":
"18.3.1", "vite": "5.3.1") so all entries under "dependencies" and
"devDependencies" are pinned; update the entries for lucide-react, react,
react-dom, `@vitejs/plugin-react`, autoprefixer, postcss, tailwindcss, and vite
accordingly to their exact x.y.z values.
| "@vitejs/plugin-react": "^4.3.1", | ||
| "autoprefixer": "^10.4.19", | ||
| "postcss": "^8.4.38", | ||
| "tailwindcss": "^3.4.4", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and print the relevant package.json with line numbers
FILE="kits/research-paper-analyzer/apps/frontend/package.json"
echo "---- $FILE (tailwindcss line vicinity) ----"
nl -ba "$FILE" | sed -n '1,120p' | sed -n '15,40p'
# Search for tailwind config in this app/kit
echo "---- tailwind config files ----"
find kits/research-paper-analyzer -maxdepth 6 -type f \( -name "tailwind.config.*" -o -name "postcss.config.*" \) | sort
# Search for Tailwind v3/v4 indicators in config
echo "---- tailwind config contents (if present) ----"
for f in $(find kits/research-paper-analyzer -maxdepth 6 -type f -name "tailwind.config.*" 2>/dev/null | sort); do
echo "### $f"
nl -ba "$f" | head -n 220 | sed -n '1,120p'
done
# List CSS files within this app that would trigger the kits/**/*.css guideline
echo "---- CSS files in this app (for tailwind requirement applicability) ----"
find kits/research-paper-analyzer/apps/frontend -type f \( -name "*.css" -o -name "*.scss" -o -name "*.sass" -o -name "*.less" \) | sort
# Show any reference to tailwind directives in CSS (e.g., `@tailwind`)
echo "---- Tailwind directives in CSS ----"
rg -n "`@tailwind`|tailwindcss" kits/research-paper-analyzer/apps/frontend --glob='*.{css,scss,less,sass,ts,tsx}' || trueRepository: Lamatic/AgentKit
Length of output: 215
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="kits/research-paper-analyzer/apps/frontend/package.json"
echo "---- JSON tailwindcss dependency in $FILE ----"
python3 - <<'PY'
import json
from pathlib import Path
p=Path("kits/research-paper-analyzer/apps/frontend/package.json")
data=json.loads(p.read_text())
for section in ["dependencies","devDependencies"]:
if section in data and "tailwindcss" in data[section]:
print(f"{section}.tailwindcss = {data[section]['tailwindcss']}")
PY
echo "---- package.json lines 1-60 (for context) ----"
cat -n "$FILE" | sed -n '1,60p'
echo "---- tailwind/postcss config files under kits/research-paper-analyzer/apps/frontend ----"
find kits/research-paper-analyzer/apps/frontend -maxdepth 4 -type f \( -name "tailwind.config.*" -o -name "postcss.config.*" \) | sort
echo "---- tailwind directives in CSS under apps/frontend ----"
rg -n "`@tailwind`|tailwindcss" kits/research-paper-analyzer/apps/frontend --glob='*.{css,scss,less,sass}' || true
echo "---- list CSS files under apps/frontend ----"
find kits/research-paper-analyzer/apps/frontend -type f \( -name "*.css" -o -name "*.scss" -o -name "*.sass" -o -name "*.less" \) | sortRepository: Lamatic/AgentKit
Length of output: 1498
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "---- tailwind.config.js ----"
cat -n kits/research-paper-analyzer/apps/frontend/tailwind.config.js | sed -n '1,200p'
echo "---- postcss.config.js ----"
cat -n kits/research-paper-analyzer/apps/frontend/postcss.config.js | sed -n '1,200p'Repository: Lamatic/AgentKit
Length of output: 459
Mission risk: Tailwind v3 is powering this kit—upgrade to Tailwind CSS v4+.
kits/research-paper-analyzer/apps/frontend/package.jsonpinsdevDependencies.tailwindcssto^3.4.4(line 20), but this kit’s CSS uses Tailwind directives inapps/frontend/src/index.css(@tailwind base/components/utilities).- Upgrade
tailwindcssto a v4+ release and adjusttailwind.config.js/ PostCSS setup and any Tailwind usage insrc/index.cssfor v4 compatibility. - This kit’s
package.jsonalso uses caret ranges (not pinned versions), conflicting with the kit dependency pinning guideline.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/frontend/package.json` at line 20, Update
the frontend kit to use Tailwind CSS v4+ by changing devDependencies.tailwindcss
in package.json from "^3.4.4" to a pinned v4+ version (e.g. "4.0.0" or the exact
release you choose), then update tailwind.config.js and the PostCSS config to
the v4 config shape and plugin usage, and modify apps/frontend/src/index.css to
use any v4-compatible directive or plugin imports if needed; also replace caret
ranges in package.json devDependencies with exact pinned versions to follow kit
dependency pinning guidelines.
| plugins: { | ||
| tailwindcss: {}, | ||
| autoprefixer: {}, |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
For Tailwind CSS v4, what is the official PostCSS setup and recommended CSS entry syntax, and how does it differ from Tailwind v3's tailwindcss+autoprefixer plugin config?
💡 Result:
Tailwind CSS v4 (official) PostCSS setup 1) Install packages - Install tailwindcss, the dedicated PostCSS plugin @tailwindcss/postcss, and postcss: npm i tailwindcss @tailwindcss/postcss postcss [1]. 2) PostCSS config - In your postcss.config.mjs (or wherever PostCSS is configured), add only the Tailwind v4 PostCSS plugin: export default { plugins: { "@tailwindcss/postcss": {}, } }; [1]. 3) Recommended CSS entry syntax - In your main CSS file, import Tailwind with a regular CSS import: @import "tailwindcss"; [1][2]. - Tailwind’s v4 docs/upgrade guide explicitly note that the v3 @tailwind base/components/utilities directives are replaced by @import "tailwindcss" in v4 [2]. How this differs from Tailwind v3 (tailwindcss + autoprefixer) - In Tailwind v3, Tailwind’s PostCSS plugin is the tailwindcss package and it’s typically paired with autoprefixer in postcss.config to handle vendor prefixing. - In Tailwind v4, the PostCSS plugin has moved into a dedicated package (@tailwindcss/postcss) and the recommended PostCSS configuration shown by Tailwind contains @tailwindcss/postcss as the plugin [1]. Tailwind v4’s own v4.0 announcement also describes “zero configuration” regarding vendor prefixing/transforms by using Lightning CSS under the hood, implying autoprefixer is no longer needed in this setup [3]. - In Tailwind v3, the CSS entry file uses three @tailwind directives (base/components/utilities). Tailwind’s upgrade guide shows these v3 directives being replaced in v4 by the single @import "tailwindcss" statement [2].
Citations:
- 1: https://tailwindcss.com/docs/installation/using-postcss
- 2: https://tailwindcss.com/docs/upgrade-guide
- 3: https://tailwindcss.com/blog/tailwindcss-v4
Mission: Replace Tailwind v3 PostCSS wiring with Tailwind v4’s official setup
This postcss.config.js uses the Tailwind v3-style plugin map (tailwindcss + autoprefixer), but Tailwind v4’s official PostCSS setup is to install/use @tailwindcss/postcss and configure only that plugin:
plugins: { "@tailwindcss/postcss": {} }- In your main CSS, replace v3 directives (
@tailwind base/components/utilities) with@import "tailwindcss";
Align this kit’s Tailwind toolchain to v4 to avoid build/lint drift against the Tailwind v4+ kit styling requirement.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/frontend/postcss.config.js` around lines 2
- 4, The PostCSS plugin map currently uses the v3-style keys (plugins object
containing tailwindcss and autoprefixer); replace that plugin map so it only
registers the v4 plugin key "`@tailwindcss/postcss`" with an empty config object
and remove the separate "tailwindcss" and "autoprefixer" entries, and then
update the main CSS files to replace any v3 directives "`@tailwind`
base/components/utilities" with a single import directive '`@import`
"tailwindcss";' so the build uses Tailwind v4’s official PostCSS wiring.
| import React from "react"; | ||
| import ReactDOM from "react-dom/client"; | ||
| import App from "./App.jsx"; | ||
| import "./index.css"; | ||
|
|
||
| ReactDOM.createRoot(document.getElementById("root")).render( | ||
| <React.StrictMode> | ||
| <App /> | ||
| </React.StrictMode> | ||
| ); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the frontend app directory
ROOT="kits/research-paper-analyzer/apps/frontend/src/main.jsx"
if [ ! -f "$ROOT" ]; then
echo "Missing file: $ROOT"
ls -R kits/research-paper-analyzer/apps/frontend/src | head -n 200 || true
exit 0
fi
echo "Found $ROOT"
echo "---- Listing relevant files in src ----"
ls -la kits/research-paper-analyzer/apps/frontend/src | sed -n '1,200p'
echo "---- Show main.jsx and App.jsx if present ----"
sed -n '1,120p' kits/research-paper-analyzer/apps/frontend/src/main.jsx || true
if [ -f kits/research-paper-analyzer/apps/frontend/src/App.jsx ]; then
echo "---- App.jsx ----"
sed -n '1,200p' kits/research-paper-analyzer/apps/frontend/src/App.jsx
fi
echo "---- Check for TypeScript config ----"
for f in kits/research-paper-analyzer/apps/frontend/tsconfig*.json kits/research-paper-analyzer/apps/frontend/*tsconfig*.json; do
if [ -f "$f" ]; then
echo "Found $f"
sed -n '1,200p' "$f"
fi
done
echo "---- Check build tooling (package.json) ----"
if [ -f kits/research-paper-analyzer/apps/frontend/package.json ]; then
sed -n '1,200p' kits/research-paper-analyzer/apps/frontend/package.json
fi
echo "---- Find any existing TS entry files ----"
fd -e ts -e tsx -e d.ts main.ts main.tsx kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts App.ts App.tsx kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
echo "---- Search for main.jsx imports/entry usage ----"
rg -n "main\.jsx" kits/research-paper-analyzer/apps/frontend | head -n 50 || true
echo "---- Search for ReactDOM.createRoot usage ----"
rg -n "ReactDOM\.createRoot" kits/research-paper-analyzer/apps/frontend/src | head -n 50 || trueRepository: Lamatic/AgentKit
Length of output: 8288
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ROOT="kits/research-paper-analyzer/apps/frontend/src/main.jsx"
if [ ! -f "$ROOT" ]; then
echo "Missing file: $ROOT"
ls -R kits/research-paper-analyzer/apps/frontend/src | head -n 200 || true
exit 0
fi
echo "Found $ROOT"
echo "---- Listing relevant files in src ----"
ls -la kits/research-paper-analyzer/apps/frontend/src | sed -n '1,200p'
echo "---- Show main.jsx and App.jsx if present ----"
sed -n '1,120p' kits/research-paper-analyzer/apps/frontend/src/main.jsx || true
if [ -f kits/research-paper-analyzer/apps/frontend/src/App.jsx ]; then
echo "---- App.jsx ----"
sed -n '1,200p' kits/research-paper-analyzer/apps/frontend/src/App.jsx
fi
echo "---- Check for TypeScript config ----"
for f in kits/research-paper-analyzer/apps/frontend/tsconfig*.json kits/research-paper-analyzer/apps/frontend/*tsconfig*.json; do
if [ -f "$f" ]; then
echo "Found $f"
sed -n '1,200p' "$f"
fi
done
echo "---- Check build tooling (package.json) ----"
if [ -f kits/research-paper-analyzer/apps/frontend/package.json ]; then
sed -n '1,200p' kits/research-paper-analyzer/apps/frontend/package.json
fi
echo "---- Find any existing TS entry files ----"
fd -e ts -e tsx -e d.ts "main.ts" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts "main.tsx" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts "App.tsx" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts "App.ts" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
echo "---- Search for main.jsx imports/entry usage ----"
rg -n "main\.jsx" kits/research-paper-analyzer/apps/frontend | head -n 50 || true
echo "---- Search for ReactDOM.createRoot usage ----"
rg -n "ReactDOM\.createRoot" kits/research-paper-analyzer/apps/frontend/src | head -n 50 || trueRepository: Lamatic/AgentKit
Length of output: 8288
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ROOT="kits/research-paper-analyzer/apps/frontend/src/main.jsx"
if [ ! -f "$ROOT" ]; then
echo "Missing file: $ROOT"
ls -R kits/research-paper-analyzer/apps/frontend/src | head -n 200 || true
exit 0
fi
echo "Found $ROOT"
echo "---- Listing relevant files in src ----"
ls -la kits/research-paper-analyzer/apps/frontend/src | sed -n '1,200p'
echo "---- Show main.jsx and App.jsx if present ----"
sed -n '1,120p' kits/research-paper-analyzer/apps/frontend/src/main.jsx || true
if [ -f kits/research-paper-analyzer/apps/frontend/src/App.jsx ]; then
echo "---- App.jsx ----"
sed -n '1,200p' kits/research-paper-analyzer/apps/frontend/src/App.jsx
fi
echo "---- Check for TypeScript config ----"
for f in kits/research-paper-analyzer/apps/frontend/tsconfig*.json kits/research-paper-analyzer/apps/frontend/*tsconfig*.json; do
if [ -f "$f" ]; then
echo "Found $f"
sed -n '1,200p' "$f"
fi
done
echo "---- Check build tooling (package.json) ----"
if [ -f kits/research-paper-analyzer/apps/frontend/package.json ]; then
sed -n '1,200p' kits/research-paper-analyzer/apps/frontend/package.json
fi
echo "---- Find any existing TS entry files ----"
fd -e ts -e tsx -e d.ts "main.ts" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts "main.tsx" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts "App.tsx" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts "App.ts" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
echo "---- Search for main.jsx imports/entry usage ----"
rg -n "main\.jsx" kits/research-paper-analyzer/apps/frontend | head -n 50 || true
echo "---- Search for ReactDOM.createRoot usage ----"
rg -n "ReactDOM\.createRoot" kits/research-paper-analyzer/apps/frontend/src | head -n 50 || trueRepository: Lamatic/AgentKit
Length of output: 8288
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ROOT="kits/research-paper-analyzer/apps/frontend/src/main.jsx"
if [ ! -f "$ROOT" ]; then
echo "Missing file: $ROOT"
ls -R kits/research-paper-analyzer/apps/frontend/src | head -n 200 || true
exit 0
fi
echo "Found $ROOT"
echo "---- Listing relevant files in src ----"
ls -la kits/research-paper-analyzer/apps/frontend/src | sed -n '1,200p'
echo "---- Show main.jsx and App.jsx if present ----"
sed -n '1,120p' kits/research-paper-analyzer/apps/frontend/src/main.jsx || true
if [ -f kits/research-paper-analyzer/apps/frontend/src/App.jsx ]; then
echo "---- App.jsx ----"
sed -n '1,200p' kits/research-paper-analyzer/apps/frontend/src/App.jsx
fi
echo "---- Check for TypeScript config ----"
for f in kits/research-paper-analyzer/apps/frontend/tsconfig*.json kits/research-paper-analyzer/apps/frontend/*tsconfig*.json; do
if [ -f "$f" ]; then
echo "Found $f"
sed -n '1,200p' "$f"
fi
done
echo "---- Check build tooling (package.json) ----"
if [ -f kits/research-paper-analyzer/apps/frontend/package.json ]; then
sed -n '1,200p' kits/research-paper-analyzer/apps/frontend/package.json
fi
echo "---- Find any existing TS entry files ----"
fd -e ts -e tsx -e d.ts "main.ts" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts "main.tsx" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts "App.tsx" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
fd -e ts -e tsx -e d.ts "App.ts" kits/research-paper-analyzer/apps/frontend/src 2>/dev/null | head -n 50 || true
echo "---- Search for main.jsx imports/entry usage ----"
rg -n "main\.jsx" kits/research-paper-analyzer/apps/frontend | head -n 50 || true
echo "---- Search for ReactDOM.createRoot usage ----"
rg -n "ReactDOM\.createRoot" kits/research-paper-analyzer/apps/frontend/src | head -n 50 || trueRepository: Lamatic/AgentKit
Length of output: 8288
🏁 Script executed:
#!/bin/bash
set -euo pipefail
KIT="kits/research-paper-analyzer/apps/frontend"
echo "---- Searching for tsconfig in the kit ----"
fd -a "tsconfig*.json" "$KIT" .. | head -n 50 || true
echo "---- Searching for any .ts/.tsx files in frontend/src ----"
fd -e ts -e tsx -e d.ts "$KIT/src" | head -n 50 || true
echo "---- Checking if TypeScript is already a dependency ----"
if [ -f "$KIT/package.json" ]; then
rg -n "\"typescript\"" "$KIT/package.json" || true
fi
echo "---- Show frontend index.html ----"
sed -n '1,80p' "$KIT/index.html" || true
echo "---- Search for existing main.tsx entry usage elsewhere in kit ----"
rg -n "main\.tsx|main\.ts" "$KIT" || trueRepository: Lamatic/AgentKit
Length of output: 2305
🏁 Script executed:
#!/bin/bash
set -euo pipefail
KIT="kits/research-paper-analyzer/apps/frontend"
echo "---- List frontend kit root files (to find config) ----"
ls -la "$KIT" | sed -n '1,200p'
echo "---- Find tsconfig files under this kit (any depth) ----"
fd -a "tsconfig*.json" "$KIT" .. | head -n 50 || true
echo "---- Check for TypeScript dependency (kit package.json, and workspace if present) ----"
if [ -f "$KIT/package.json" ]; then
echo "--- $KIT/package.json (typescript lines) ---"
rg -n "\"typescript\"" "$KIT/package.json" || true
fi
# Also search for nearest package.json up the tree that might declare TS.
for dir in "$KIT" "$KIT/.." "$KIT/../.."; do
if [ -f "$dir/package.json" ]; then
echo "--- $dir/package.json (typescript lines) ---"
rg -n "\"typescript\"" "$dir/package.json" || true
fi
done
echo "---- Check for Vite config ----"
fd -e "vite.config.*" -a "$KIT" .. | head -n 20 || true
ls -la "$KIT" | rg -n "vite\.config" || true
# Try common filenames directly (safe if missing)
for f in "$KIT/vite.config.js" "$KIT/vite.config.ts" "$KIT/vite.config.mjs" "$KIT/vite.config.cjs"; do
if [ -f "$f" ]; then
echo "---- $f ----"
sed -n '1,200p' "$f"
fi
done
echo "---- Search for Vite entry in index.html / other config ----"
sed -n '1,120p' "$KIT/index.html" || trueRepository: Lamatic/AgentKit
Length of output: 3475
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Count occurrences of main.jsx and main.tsx across kits
echo "---- Searching for main.jsx across kits ----"
rg -n --hidden --glob 'kits/**/apps/**/main.jsx' 'ReactDOM\.createRoot|main\.jsx' | head -n 50 || true
echo "---- Searching for main.tsx across kits ----"
rg -n --hidden --glob 'kits/**/apps/**/main.tsx' 'ReactDOM\.createRoot|main\.tsx' | head -n 50 || true
echo "---- Any tsconfig near kits/*/apps/* that uses React DOM entrypoints ----"
fd -a 'tsconfig*.json' kits -tf | head -n 50 || true
echo "---- Check if this repo uses any .jsx within kits/**/apps/**/src ----"
rg -n --hidden --glob 'kits/**/apps/**/src/**/*.jsx' 'export default function|import React|ReactDOM' | head -n 50 || trueRepository: Lamatic/AgentKit
Length of output: 2124
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Count .jsx/.tsx under kits/*/apps
echo "---- Count .jsx under kits/**/apps/**/src ----"
rg -l --hidden --glob 'kits/**/apps/**/src/**/*.jsx' '.' | wc -l || true
echo "---- Count .tsx under kits/**/apps/**/src ----"
rg -l --hidden --glob 'kits/**/apps/**/src/**/*.tsx' '.' | wc -l || true
echo "---- Sample .jsx files (up to 20) ----"
rg -l --hidden --glob 'kits/**/apps/**/src/**/*.jsx' '.' | head -n 20 || true
echo "---- Sample .tsx files (up to 20) ----"
rg -l --hidden --glob 'kits/**/apps/**/src/**/*.tsx' '.' | head -n 20 || trueRepository: Lamatic/AgentKit
Length of output: 663
Mission directive: convert the frontend bootstrap to TypeScript/TSX (and update wiring).
In kits/research-paper-analyzer/apps/frontend/src/, the app entrypoints are still JSX (main.jsx importing App.jsx), and index.html hardcodes /src/main.jsx. This breaks the kit policy requiring kits/**/*.{ts,tsx}.
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import "./index.css";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<App />
</React.StrictMode>
);- Rename
main.jsx→main.tsxandApp.jsx→App.tsx(update the import inmainaccordingly). - Update
apps/frontend/index.htmlto load/src/main.tsx. - Ensure TypeScript tooling exists for this kit (no
tsconfig*.jsonand notypescriptdependency are present right now), otherwise the rename won’t compile.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/frontend/src/main.jsx` around lines 1 - 10,
The project entry uses JSX files (main.jsx importing App.jsx) and index.html
still references /src/main.jsx which violates the kit policy requiring
TypeScript; rename main.jsx → main.tsx and App.jsx → App.tsx, update the import
in main (change import "./App.jsx" to import "./App.tsx") and update
apps/frontend/index.html to load /src/main.tsx; finally add TypeScript support
by adding a tsconfig.json (basic React/JSX settings) and ensure "typescript" is
added as a devDependency so the renamed .ts/.tsx files compile.
| outputSchema: JSON.stringify({ | ||
| type: "object", | ||
| properties: { | ||
| title: { type: "string" }, | ||
| authors: { type: "array", items: { type: "string" } }, | ||
| year: { type: ["number", "null"] }, | ||
| problem_statement: { type: "string" }, | ||
| methodology: { type: "string" }, | ||
| key_findings: { type: "array", items: { type: "string" } }, | ||
| limitations: { type: "array", items: { type: "string" } }, | ||
| plain_english_summary: { type: "string" }, | ||
| follow_up_questions: { type: "array", items: { type: "string" } }, | ||
| }, | ||
| required: [ | ||
| "title", | ||
| "authors", | ||
| "year", | ||
| "problem_statement", | ||
| "methodology", | ||
| "key_findings", | ||
| "limitations", | ||
| "plain_english_summary", | ||
| "follow_up_questions", | ||
| ], | ||
| }), |
There was a problem hiding this comment.
Mission-critical: the schema blocks your documented non-paper fallback.
agent.md and constitutions/default.md both instruct the model to return an error object when the upload is not an academic paper, but this schema only accepts the full analysis payload. That turns the documented fallback into a flow validation failure and a 500 from /analyze. Add an explicit error variant here, or keep a single response shape with a status/error field.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/flows/research-paper-analyzer.ts` around lines
109 - 133, The current outputSchema (the JSON.stringify passed to outputSchema
in research-paper-analyzer.ts) only allows the full analysis shape and therefore
rejects the documented non-paper fallback; modify that JSON schema to include an
explicit error variant (e.g., a oneOf with the existing object and a second
object with properties like status: {type:"string"}, error: {type:"string"},
details: {type:"object", additionalProperties:true}) or change the single
response shape to include a status and optional error field (add "status" and
"error" to properties and make the original analysis properties optional), and
update the required array accordingly so the flow will accept the documented
error response from agent.md/constitutions/default.md.
| export default { | ||
| name: "Research Paper Analyzer", | ||
| description: | ||
| "Upload any academic PDF and get a structured breakdown: problem statement, methodology, key findings, limitations, plain-English summary, and follow-up research questions.", | ||
| version: "1.0.0", | ||
| type: "kit" as const, | ||
| author: { name: "Suhas Chowdary", email: "suhaschowdary25@gmail.com" }, | ||
| tags: ["research", "education", "pdf", "summarization", "academia"], | ||
| steps: [ | ||
| { id: "research-paper-analyzer", type: "mandatory" as const, envKey: "RESEARCH_PAPER_ANALYZER_FLOW_ID" }, | ||
| ], | ||
| links: { | ||
| github: "https://github.com/Lamatic/AgentKit/tree/main/kits/research-paper-analyzer", | ||
| deploy: | ||
| "https://vercel.com/new/clone?repository-url=https://github.com/Lamatic/AgentKit&root-directory=kits%2Fresearch-paper-analyzer%2Fapps&env=RESEARCH_PAPER_ANALYZER_FLOW_ID,LAMATIC_API_URL,LAMATIC_PROJECT_ID,LAMATIC_API_KEY&envDescription=Your%20Lamatic%20Research%20Paper%20Analyzer%20keys%20are%20required.&envLink=https://lamatic.ai/docs", | ||
| docs: "https://lamatic.ai/docs", | ||
| }, | ||
| }; |
There was a problem hiding this comment.
Mission-critical: move this kit under a supported category directory.
This file lives at kits/research-paper-analyzer/..., but the repo contract requires kits/<category>/<kit-name>/. Leaving it here can break kit discovery and the hardcoded links in this config will have to move with it.
As per coding guidelines, Kit folder structure must follow the pattern kits/<category>/<kit-name>/ where category is one of: agentic, assistant, automation, embed.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/lamatic.config.ts` around lines 1 - 18, This kit
config is in the wrong directory; move the entire kit folder into the required
pattern kits/<category>/<kit-name> (choose one of the allowed categories:
agentic, assistant, automation, embed) and update the config's path-sensitive
fields accordingly: adjust links.github and links.deploy (root-directory query
param) to reflect the new directory layout, and verify the exported object (name
"Research Paper Analyzer", steps array with id "research-paper-analyzer", and
envKey "RESEARCH_PAPER_ANALYZER_FLOW_ID") still matches the relocated folder and
any tooling that consumes it.
| Rules: | ||
| - Base everything strictly on the paper content provided | ||
| - If a field cannot be determined from the text, use null (for scalars) or [] (for arrays) | ||
| - Do not include any text outside the JSON object | ||
| - Return only valid JSON |
There was a problem hiding this comment.
Mission-critical: the fallback rule disagrees with the flow schema.
This prompt tells the model to use null for any missing scalar, but flows/research-paper-analyzer.ts only allows year to be null. Missing title, problem_statement, methodology, or plain_english_summary will fail output validation instead of degrading cleanly. Normalize on one contract.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/prompts/analyze-paper.md` around lines 18 - 22,
The prompt fallback rule ("use null for any missing scalar") conflicts with the
flow schema in flows/research-paper-analyzer.ts which only permits year to be
null; pick one contract and implement it: either (A) update
prompts/analyze-paper.md to remove the blanket "use null" rule and state that
only year may be null (ensuring title, problem_statement, methodology,
plain_english_summary must be present), or (B) update the flow/schema/types in
flows/research-paper-analyzer.ts to allow null for the scalar fields title,
problem_statement, methodology, and plain_english_summary (make their types
nullable and adjust validation). Reference the file analyze-paper.md and the
flow/research-paper-analyzer.ts fields (title, problem_statement, methodology,
plain_english_summary, year) when making the change so prompt and schema agree.
| ``` | ||
| React (Vite/JSX) → FastAPI (Python) → Lamatic Flow → LLM | ||
| frontend backend orchestration | ||
| localhost:5173 localhost:8000 | ||
| ``` | ||
|
|
There was a problem hiding this comment.
Mission brief: neutralize markdownlint blockers before merge.
At Line 18 and Line 52, fenced blocks are missing language tags (MD040). Around Line 52, Line 91, and Line 96, add blank lines around fenced blocks (MD031) to satisfy the validator.
Proposed patch
## Architecture
-```
+```text
React (Vite/JSX) → FastAPI (Python) → Lamatic Flow → LLM
frontend backend orchestration
localhost:5173 localhost:8000@@
.env values to fill in:
- + +env
RESEARCH_PAPER_ANALYZER_FLOW_ID=
LAMATIC_API_URL=
LAMATIC_PROJECT_ID=
LAMATIC_API_KEY=
@@
### `POST /analyze`
**Request:**
+
```json
{ "pdf_url": "https://arxiv.org/pdf/2303.08774.pdf" }
Response:
+
{
"success": true,Also applies to: 52-57, 91-93, 96-111
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 18-18: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/README.md` around lines 18 - 23, Several fenced
code blocks in the README (e.g., the ASCII diagram starting "React (Vite/JSX) →
FastAPI (Python) → Lamatic Flow → LLM", the `.env` block beginning with
RESEARCH_PAPER_ANALYZER_FLOW_ID, and the JSON examples used under "POST
/analyze") are missing language tags (MD040) and lack surrounding blank lines
(MD031); update each fenced block to include the appropriate language tag (e.g.,
```text, ```env, ```json) and ensure there is a blank line before and after
every fenced block so the validator passes, targeting the blocks that contain
the ASCII diagram, the `.env` variables, and the request/response JSON examples.
:robot_face: AgentKit Structural ValidationNew Contributions Detected
Check Results
🎉 All checks passed! This contribution follows the AgentKit structure. |
|
Failure recorded at 2026-06-03T15:48:18Z UTC. If this PR is not fixed within 4 weeks it will be automatically closed. |
|
Hello @Suhas-123-cell Please fix these issues before we merge! Kit kits/research-paper-analyzer is missing apps/package.json — kits must include a Next.js app You can checkout the github action and code rabbit comment above for more context |
Replace Vite+React frontend and FastAPI backend with a Next.js 15 app at apps/ root. Adds apps/package.json, apps/.env.example, Server Action calling Lamatic directly, and root-level .env.example — fixes all three CI errors on PR Lamatic#163.
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
kits/research-paper-analyzer/apps/components/analyzer.tsx (2)
90-106: 🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoffRecommend shadcn/ui Button for submit action.
Agent, your submit button should use shadcn/ui's Button component to maintain consistency with kit UI standards and leverage built-in accessibility features.
See the shadcn/ui integration suggestion in the previous comment for the input field - the same pattern applies here for the Button component.
As per coding guidelines: "Use shadcn/ui and Radix UI primitives for UI components in kits."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/research-paper-analyzer/apps/components/analyzer.tsx` around lines 90 - 106, Replace the native <button type="submit" ...> element in the Analyzer component with the shadcn/ui Button component (the current element around the loading state and icons), preserving the disabled={loading || !pdfUrl.trim()} logic and swapping the inner JSX exactly (Loader2 + "Analyzing paper…" when loading, Search + "Analyze Paper" otherwise); import and use the Button component, map existing props (type="submit", classNames/variant/styles, aria attributes if any) to the Button API so styling, focus, and accessibility are preserved and the icons and loading state continue to render correctly.
81-88: 🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoffRecommend shadcn/ui components for UI consistency.
Agent, while your custom input implementation is functional, the kit guidelines require shadcn/ui and Radix UI primitives for UI components. This ensures accessibility, theming consistency, and reduced maintenance burden across the kit collection.
🎨 Optional: Integrate shadcn/ui Input component
Install shadcn/ui:
npx shadcn@latest init npx shadcn@latest add input buttonReplace custom input with shadcn component:
import { Input } from "`@/components/ui/input`"; import { Button } from "`@/components/ui/button`"; // In your form: <Input type="url" value={pdfUrl} onChange={(e) => setPdfUrl(e.target.value)} placeholder="https://arxiv.org/pdf/2303.08774.pdf" required />As per coding guidelines: "Use shadcn/ui and Radix UI primitives for UI components in kits."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kits/research-paper-analyzer/apps/components/analyzer.tsx` around lines 81 - 88, Replace the custom HTML input with the shadcn/ui Input component: import Input from your ui components and use <Input> in place of the current <input>, passing the same props (type="url", value={pdfUrl}, onChange={(e) => setPdfUrl(e.target.value)}, placeholder, required) and remove the handcrafted className in favor of the shadcn styling or pass className only if you need overrides; ensure you add the import for Input at the top of the file and keep the pdfUrl and setPdfUrl state references intact so behavior is unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@kits/research-paper-analyzer/.env.example`:
- Around line 1-4: The .env template wraps variable values in quotes which many
parsers treat as literal characters; remove the surrounding double quotes for
RESEARCH_PAPER_ANALYZER_FLOW_ID, LAMATIC_API_URL, LAMATIC_PROJECT_ID, and
LAMATIC_API_KEY so the lines read as bare values (e.g.,
RESEARCH_PAPER_ANALYZER_FLOW_ID=your-flow-id) to ensure the runtime values do
not include quote characters.
In `@kits/research-paper-analyzer/apps/.env.example`:
- Around line 1-4: The env template uses quoted values which can corrupt tokens;
remove the surrounding double-quotes from the variables
RESEARCH_PAPER_ANALYZER_FLOW_ID, LAMATIC_API_URL, LAMATIC_PROJECT_ID, and
LAMATIC_API_KEY so each line is VAR=value (e.g.,
RESEARCH_PAPER_ANALYZER_FLOW_ID=your-flow-id) to ensure clean environment
variable parsing and valid API keys.
In `@kits/research-paper-analyzer/apps/actions/analyze.ts`:
- Around line 24-29: The code blindly asserts result as PaperAnalysis after
calling lamaticClient.executeFlow; add runtime validation before the cast by
implementing and calling a type guard or schema validator (e.g.,
isPaperAnalysis(obj) or a Zod/Joi schema) that checks required fields and types
on result, throw a descriptive error if validation fails, and only then return {
success: true, data: result as PaperAnalysis }; reference the variables/methods
lamaticClient.executeFlow, flowId, pdfUrl and the PaperAnalysis type when
locating where to add the validation.
- Around line 17-22: analyzePaper currently trusts the client-provided pdfUrl
with no validation; add defensive validation at the start of analyzePaper to
ensure pdfUrl is a non-empty string and a well-formed HTTP/HTTPS URL (use the
URL constructor or a strict regex to parse and verify protocol), reject or
return { success: false, error: "..."} for invalid inputs, and
sanitize/normalize the URL before further use; keep the existing flowId check
and reference pdfUrl and analyzePaper when adding this validation and error
handling so malformed, empty, or non-http(s) values are explicitly blocked.
In `@kits/research-paper-analyzer/apps/app/globals.css`:
- Line 1: Create a PostCSS config module to enable Tailwind v4 processing: add a
new module named postcss.config.mjs in the app to export a config object with a
plugins map that registers the "`@tailwindcss/postcss`" plugin (so the existing
`@import` 'tailwindcss' in globals.css is actually processed). Ensure the file
exports the config as the default export and that the plugin key is exactly
"`@tailwindcss/postcss`".
In `@kits/research-paper-analyzer/apps/components/analyzer.tsx`:
- Line 1: Rename the component file from analyzer.tsx to PascalCase Analyzer.tsx
and update any imports to reference "`@/components/Analyzer`" (e.g., the import in
page.tsx that should be import { Analyzer } from "`@/components/Analyzer`";);
ensure the exported component name (Analyzer) matches the new filename and that
no other imports still reference analyzer.tsx.
- Around line 26-39: Replace the manual form state in the Analyzer component
(currently using pdfUrl, handleSubmit, setLoading, setError, setResult and
calling analyzePaper) with react-hook-form and zod validation: define a zod
schema for pdfUrl as a URL, create useForm with zodResolver, move the submission
logic into an onSubmit that receives validated data and calls
analyzePaper(data.pdfUrl), and render form errors from formState.errors instead
of manual checks; ensure loading/error/result state updates remain but are
triggered from the useForm submit handler and the form element uses
handleSubmit(onSubmit).
In `@kits/research-paper-analyzer/apps/package.json`:
- Line 13: The package.json dependency "lamatic": "latest" must be pinned to a
specific version to ensure reproducible builds; update the "lamatic" entry in
apps/package.json to an explicit semver (e.g., "lamatic": "1.2.3") by looking up
the current stable version on npm, update package-lock.json/yarn.lock via an
install (npm install or yarn install) and commit both package.json and the
updated lockfile; ensure no other dependencies use floating tags.
---
Outside diff comments:
In `@kits/research-paper-analyzer/apps/components/analyzer.tsx`:
- Around line 90-106: Replace the native <button type="submit" ...> element in
the Analyzer component with the shadcn/ui Button component (the current element
around the loading state and icons), preserving the disabled={loading ||
!pdfUrl.trim()} logic and swapping the inner JSX exactly (Loader2 + "Analyzing
paper…" when loading, Search + "Analyze Paper" otherwise); import and use the
Button component, map existing props (type="submit", classNames/variant/styles,
aria attributes if any) to the Button API so styling, focus, and accessibility
are preserved and the icons and loading state continue to render correctly.
- Around line 81-88: Replace the custom HTML input with the shadcn/ui Input
component: import Input from your ui components and use <Input> in place of the
current <input>, passing the same props (type="url", value={pdfUrl},
onChange={(e) => setPdfUrl(e.target.value)}, placeholder, required) and remove
the handcrafted className in favor of the shadcn styling or pass className only
if you need overrides; ensure you add the import for Input at the top of the
file and keep the pdfUrl and setPdfUrl state references intact so behavior is
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: fc0a831a-c0fe-4a99-ab19-3c10fb2e887e
📒 Files selected for processing (10)
kits/research-paper-analyzer/.env.examplekits/research-paper-analyzer/apps/.env.examplekits/research-paper-analyzer/apps/actions/analyze.tskits/research-paper-analyzer/apps/app/globals.csskits/research-paper-analyzer/apps/app/layout.tsxkits/research-paper-analyzer/apps/app/page.tsxkits/research-paper-analyzer/apps/components/analyzer.tsxkits/research-paper-analyzer/apps/lib/lamatic-client.tskits/research-paper-analyzer/apps/next.config.mjskits/research-paper-analyzer/apps/package.json
| RESEARCH_PAPER_ANALYZER_FLOW_ID="your-flow-id" | ||
| LAMATIC_API_URL="https://your-project.lamatic.ai" | ||
| LAMATIC_PROJECT_ID="your-project-id" | ||
| LAMATIC_API_KEY="your-api-key" |
There was a problem hiding this comment.
Field report: Unnecessary quote characters detected in .env template.
Agent, your environment variable values are wrapped in quotes. Most .env parsers read these literally—meaning your actual runtime values will include the quote characters themselves. This can cause authentication failures or unexpected string matching issues.
Mission directive: Remove quotes for clean parsing.
🔧 Suggested correction
-RESEARCH_PAPER_ANALYZER_FLOW_ID="your-flow-id"
-LAMATIC_API_URL="https://your-project.lamatic.ai"
-LAMATIC_PROJECT_ID="your-project-id"
-LAMATIC_API_KEY="your-api-key"
+RESEARCH_PAPER_ANALYZER_FLOW_ID=your-flow-id
+LAMATIC_API_URL=https://your-project.lamatic.ai
+LAMATIC_PROJECT_ID=your-project-id
+LAMATIC_API_KEY=your-api-key📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| RESEARCH_PAPER_ANALYZER_FLOW_ID="your-flow-id" | |
| LAMATIC_API_URL="https://your-project.lamatic.ai" | |
| LAMATIC_PROJECT_ID="your-project-id" | |
| LAMATIC_API_KEY="your-api-key" | |
| RESEARCH_PAPER_ANALYZER_FLOW_ID=your-flow-id | |
| LAMATIC_API_URL=https://your-project.lamatic.ai | |
| LAMATIC_PROJECT_ID=your-project-id | |
| LAMATIC_API_KEY=your-api-key |
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 1-1: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 2-2: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 2-2: [UnorderedKey] The LAMATIC_API_URL key should go before the RESEARCH_PAPER_ANALYZER_FLOW_ID key
(UnorderedKey)
[warning] 3-3: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 3-3: [UnorderedKey] The LAMATIC_PROJECT_ID key should go before the RESEARCH_PAPER_ANALYZER_FLOW_ID key
(UnorderedKey)
[warning] 4-4: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 4-4: [UnorderedKey] The LAMATIC_API_KEY key should go before the LAMATIC_API_URL key
(UnorderedKey)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/.env.example` around lines 1 - 4, The .env
template wraps variable values in quotes which many parsers treat as literal
characters; remove the surrounding double quotes for
RESEARCH_PAPER_ANALYZER_FLOW_ID, LAMATIC_API_URL, LAMATIC_PROJECT_ID, and
LAMATIC_API_KEY so the lines read as bare values (e.g.,
RESEARCH_PAPER_ANALYZER_FLOW_ID=your-flow-id) to ensure the runtime values do
not include quote characters.
| RESEARCH_PAPER_ANALYZER_FLOW_ID="your-flow-id" | ||
| LAMATIC_API_URL="https://your-project.lamatic.ai" | ||
| LAMATIC_PROJECT_ID="your-project-id" | ||
| LAMATIC_API_KEY="your-api-key" |
There was a problem hiding this comment.
Surveillance confirms: Identical quote character issue in apps/.env.example.
This template mirrors the same vulnerability as the root .env.example. Remove the quotes to ensure clean environment variable parsing and prevent authentication token corruption.
🔧 Suggested correction
-RESEARCH_PAPER_ANALYZER_FLOW_ID="your-flow-id"
-LAMATIC_API_URL="https://your-project.lamatic.ai"
-LAMATIC_PROJECT_ID="your-project-id"
-LAMATIC_API_KEY="your-api-key"
+RESEARCH_PAPER_ANALYZER_FLOW_ID=your-flow-id
+LAMATIC_API_URL=https://your-project.lamatic.ai
+LAMATIC_PROJECT_ID=your-project-id
+LAMATIC_API_KEY=your-api-key📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| RESEARCH_PAPER_ANALYZER_FLOW_ID="your-flow-id" | |
| LAMATIC_API_URL="https://your-project.lamatic.ai" | |
| LAMATIC_PROJECT_ID="your-project-id" | |
| LAMATIC_API_KEY="your-api-key" | |
| RESEARCH_PAPER_ANALYZER_FLOW_ID=your-flow-id | |
| LAMATIC_API_URL=https://your-project.lamatic.ai | |
| LAMATIC_PROJECT_ID=your-project-id | |
| LAMATIC_API_KEY=your-api-key |
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 1-1: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 2-2: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 2-2: [UnorderedKey] The LAMATIC_API_URL key should go before the RESEARCH_PAPER_ANALYZER_FLOW_ID key
(UnorderedKey)
[warning] 3-3: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 3-3: [UnorderedKey] The LAMATIC_PROJECT_ID key should go before the RESEARCH_PAPER_ANALYZER_FLOW_ID key
(UnorderedKey)
[warning] 4-4: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 4-4: [UnorderedKey] The LAMATIC_API_KEY key should go before the LAMATIC_API_URL key
(UnorderedKey)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/.env.example` around lines 1 - 4, The env
template uses quoted values which can corrupt tokens; remove the surrounding
double-quotes from the variables RESEARCH_PAPER_ANALYZER_FLOW_ID,
LAMATIC_API_URL, LAMATIC_PROJECT_ID, and LAMATIC_API_KEY so each line is
VAR=value (e.g., RESEARCH_PAPER_ANALYZER_FLOW_ID=your-flow-id) to ensure clean
environment variable parsing and valid API keys.
| export async function analyzePaper( | ||
| pdfUrl: string | ||
| ): Promise<{ success: boolean; data?: PaperAnalysis; error?: string }> { | ||
| try { | ||
| const flowId = process.env.RESEARCH_PAPER_ANALYZER_FLOW_ID; | ||
| if (!flowId) throw new Error("RESEARCH_PAPER_ANALYZER_FLOW_ID is not set."); |
There was a problem hiding this comment.
Mission briefing: Critical security gap detected in parameter validation.
Agent, your function accepts a pdfUrl parameter from the client with zero validation. An adversary could transmit empty strings, malformed URLs, or potentially malicious payloads. Server actions must never trust client input.
Recommended defensive protocol:
🛡️ Suggested validation enhancement
export async function analyzePaper(
pdfUrl: string
): Promise<{ success: boolean; data?: PaperAnalysis; error?: string }> {
try {
+ // Validate input
+ if (!pdfUrl || !pdfUrl.trim()) {
+ throw new Error("PDF URL is required.");
+ }
+
+ // Validate URL format
+ try {
+ new URL(pdfUrl);
+ } catch {
+ throw new Error("Invalid PDF URL format.");
+ }
+
const flowId = process.env.RESEARCH_PAPER_ANALYZER_FLOW_ID;
if (!flowId) throw new Error("RESEARCH_PAPER_ANALYZER_FLOW_ID is not set.");📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export async function analyzePaper( | |
| pdfUrl: string | |
| ): Promise<{ success: boolean; data?: PaperAnalysis; error?: string }> { | |
| try { | |
| const flowId = process.env.RESEARCH_PAPER_ANALYZER_FLOW_ID; | |
| if (!flowId) throw new Error("RESEARCH_PAPER_ANALYZER_FLOW_ID is not set."); | |
| export async function analyzePaper( | |
| pdfUrl: string | |
| ): Promise<{ success: boolean; data?: PaperAnalysis; error?: string }> { | |
| try { | |
| // Validate input | |
| if (!pdfUrl || !pdfUrl.trim()) { | |
| throw new Error("PDF URL is required."); | |
| } | |
| // Validate URL format | |
| try { | |
| new URL(pdfUrl); | |
| } catch { | |
| throw new Error("Invalid PDF URL format."); | |
| } | |
| const flowId = process.env.RESEARCH_PAPER_ANALYZER_FLOW_ID; | |
| if (!flowId) throw new Error("RESEARCH_PAPER_ANALYZER_FLOW_ID is not set."); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/actions/analyze.ts` around lines 17 - 22,
analyzePaper currently trusts the client-provided pdfUrl with no validation; add
defensive validation at the start of analyzePaper to ensure pdfUrl is a
non-empty string and a well-formed HTTP/HTTPS URL (use the URL constructor or a
strict regex to parse and verify protocol), reject or return { success: false,
error: "..."} for invalid inputs, and sanitize/normalize the URL before further
use; keep the existing flowId check and reference pdfUrl and analyzePaper when
adding this validation and error handling so malformed, empty, or non-http(s)
values are explicitly blocked.
| const resData = await lamaticClient.executeFlow(flowId, { pdf_url: pdfUrl }); | ||
| const result = resData?.result ?? resData?.output ?? resData; | ||
|
|
||
| if (!result) throw new Error("No result returned from the flow."); | ||
|
|
||
| return { success: true, data: result as PaperAnalysis }; |
There was a problem hiding this comment.
Intelligence report: Type assertion without runtime validation detected.
Your mission uses an unchecked type cast at line 29 (as PaperAnalysis). If the Lamatic flow returns a different structure—missing fields, wrong types, or partial data—the type system won't protect you. The UI will encounter runtime failures when accessing non-existent properties.
Recommended validation protocol:
🔍 Suggested runtime validation
const resData = await lamaticClient.executeFlow(flowId, { pdf_url: pdfUrl });
const result = resData?.result ?? resData?.output ?? resData;
- if (!result) throw new Error("No result returned from the flow.");
+ // Validate response structure
+ if (!result || typeof result !== "object") {
+ throw new Error("No valid result returned from the flow.");
+ }
+
+ // Validate required fields
+ const required = ["title", "authors", "year", "problem_statement", "methodology",
+ "key_findings", "limitations", "plain_english_summary", "follow_up_questions"];
+ const missing = required.filter(field => !(field in result));
+ if (missing.length > 0) {
+ throw new Error(`Flow response missing required fields: ${missing.join(", ")}`);
+ }
- return { success: true, data: result as PaperAnalysis };
+ return { success: true, data: result as PaperAnalysis };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const resData = await lamaticClient.executeFlow(flowId, { pdf_url: pdfUrl }); | |
| const result = resData?.result ?? resData?.output ?? resData; | |
| if (!result) throw new Error("No result returned from the flow."); | |
| return { success: true, data: result as PaperAnalysis }; | |
| const resData = await lamaticClient.executeFlow(flowId, { pdf_url: pdfUrl }); | |
| const result = resData?.result ?? resData?.output ?? resData; | |
| // Validate response structure | |
| if (!result || typeof result !== "object") { | |
| throw new Error("No valid result returned from the flow."); | |
| } | |
| // Validate required fields | |
| const required = ["title", "authors", "year", "problem_statement", "methodology", | |
| "key_findings", "limitations", "plain_english_summary", "follow_up_questions"]; | |
| const missing = required.filter(field => !(field in result)); | |
| if (missing.length > 0) { | |
| throw new Error(`Flow response missing required fields: ${missing.join(", ")}`); | |
| } | |
| return { success: true, data: result as PaperAnalysis }; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/actions/analyze.ts` around lines 24 - 29,
The code blindly asserts result as PaperAnalysis after calling
lamaticClient.executeFlow; add runtime validation before the cast by
implementing and calling a type guard or schema validator (e.g.,
isPaperAnalysis(obj) or a Zod/Joi schema) that checks required fields and types
on result, throw a descriptive error if validation fails, and only then return {
success: true, data: result as PaperAnalysis }; reference the variables/methods
lamaticClient.executeFlow, flowId, pdfUrl and the PaperAnalysis type when
locating where to add the validation.
| @@ -0,0 +1 @@ | |||
| @import 'tailwindcss'; | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether other kits in this repo use explicit postcss.config.js with Tailwind v4
fd -t f '^postcss\.config\.(js|mjs)$' kits/ --exec echo "Found: {}"Repository: Lamatic/AgentKit
Length of output: 915
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Check whether this specific kit has an explicit postcss config
fd -t f '^postcss\.config\.(js|mjs)$' kits/research-paper-analyzer --exec echo "Found in research-paper-analyzer: {}" || true
# 2) Find all occurrences of Tailwind v4 import style and show nearby context (and whether a postcss config exists per kit)
rg -n "`@import` 'tailwindcss';" kits --glob='*.css' --glob='*.pcss' | head -n 50
# 3) Locate package.json files for the research-paper-analyzer app and print dependency versions for next/tailwind/postcss (small extraction)
# (Use jq if present; otherwise grep.)
find kits/research-paper-analyzer -maxdepth 4 -name package.json -print | head -n 20
# Try to extract relevant deps from any found package.json under the app
find kits/research-paper-analyzer -maxdepth 6 -name package.json -print0 | \
python3 - <<'PY'
import json,sys,os,glob
paths = [p for p in glob.glob('kits/research-paper-analyzer/**/package.json', recursive=True)]
for p in paths:
try:
with open(p,'r',encoding='utf-8') as f:
data=json.load(f)
deps={}
for k in ['dependencies','devDependencies','peerDependencies']:
deps.update(data.get(k,{}))
keys=['next','tailwindcss','postcss']
got={k:deps.get(k) for k in keys if k in deps}
if got:
print(p)
for k,v in got.items():
print(f" {k}: {v}")
except Exception as e:
pass
PY
# 4) Inspect one representative PostCSS config from another kit to see wiring pattern
# Pick hiring-copilot-agent since it was mentioned in the original comment's example area.
if [ -f kits/hiring-copilot-agent/apps/postcss.config.mjs ]; then
echo "---- hiring-copilot-agent/apps/postcss.config.mjs ----"
sed -n '1,120p' kits/hiring-copilot-agent/apps/postcss.config.mjs
fiRepository: Lamatic/AgentKit
Length of output: 1193
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Does research-paper-analyzer define an explicit PostCSS config?
echo "== postcss.config.* under kits/research-paper-analyzer =="
fd -t f '^postcss\.config\.(js|mjs)$' kits/research-paper-analyzer --exec echo "Found: {}" || true
# 2) Show the tailwind/postcss/next parts of its package.json
echo
echo "== kits/research-paper-analyzer/apps/package.json (relevant deps) =="
cat kits/research-paper-analyzer/apps/package.json | rg -n '"(next|tailwindcss|postcss)"\s*:' -n
# 3) Show one PostCSS config from another kit that uses Tailwind v4 import
echo
echo "== Example postcss.config from a sibling kit =="
if [ -f kits/hiring-copilot-agent/apps/postcss.config.mjs ]; then
sed -n '1,160p' kits/hiring-copilot-agent/apps/postcss.config.mjs
else
# fallback: pick the first postcss.config.* found under kits/
cfg="$(fd -t f '^postcss\.config\.(js|mjs)$' kits --exec echo {} | head -n 1)"
echo "Using: $cfg"
sed -n '1,160p' "$cfg"
fiRepository: Lamatic/AgentKit
Length of output: 414
🌐 Web query:
Next.js 15 Tailwind CSS v4 @import'tailwindcss' postcss.config not required@tailwindcss/postcss auto-detect
💡 Result:
In Next.js 15, while Tailwind CSS v4 features automatic content detection [1][2][3], a postcss.config.mjs file remains a required integration point to hook the Tailwind engine into the Next.js build pipeline [4][2][3]. The setup for Tailwind CSS v4 in Next.js 15 follows these core requirements: 1. PostCSS Configuration: You must create a postcss.config.mjs (or postcss.config.js) file that explicitly includes the @tailwindcss/postcss plugin [5][6][4]. This is the required adapter for Tailwind v4 [4][2][3]. postcss.config.mjs export default { plugins: { "@tailwindcss/postcss": {}, }, }; 2. CSS Import: Replace the legacy v3 @tailwind directives (base, components, utilities) with a single import in your global CSS file (typically app/globals.css) [5][1][3]: @import "tailwindcss"; 3. Automatic Content Detection: Tailwind v4 handles content scanning automatically using its new Oxide engine, eliminating the need for a tailwind.config.js file for content paths [1][3]. If you have legacy customizations, they should be migrated to CSS variables within a @theme block in your CSS file rather than a JavaScript config file [7][1][3]. While some modern frontend frameworks (like Vite) offer a "zero-config" experience for Tailwind v4, Next.js 15 still requires the PostCSS plugin adapter to maintain compatibility with the Next.js build and compilation process [4][3].
Citations:
- 1: https://designrevision.com/blog/tailwind-nextjs-setup
- 2: https://devradar.dev/check/tailwind-css-v4-with-nextjs-15-setup
- 3: https://dev.to/malahim_haseeb_981126d794/tailwind-css-v4-what-actually-changed-and-what-it-means-for-your-nextjs-project-472f
- 4: https://htmlgenie.net/tailwind-v4-oxide-engine-broke-my-postcss-pipeline/
- 5: https://tailwindcss.com/docs/guides/nextjs
- 6: https://nextjs.org/docs/app/getting-started/css
- 7: https://dev.to/shakewithabhi/setting-up-nextjs-15-with-tailwind-v4-and-shadcnui-what-actually-changed-2fpg
Wire Tailwind v4 PostCSS adapter for research-paper-analyzer
Agent, your mission depends on Tailwind v4 actually running in the Next build pipeline: apps/app/globals.css uses @import 'tailwindcss';, but this kit has no apps/postcss.config.(js|mjs) to include the required @tailwindcss/postcss plugin. Add kits/research-paper-analyzer/apps/postcss.config.mjs:
Add
const config = {
plugins: {
"`@tailwindcss/postcss`": {},
},
};
export default config;🧰 Tools
🪛 Stylelint (17.12.0)
[error] 1-2: Unknown rule scss/at-rule-no-unknown. Did you mean at-rule-no-unknown?
(scss/at-rule-no-unknown)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/app/globals.css` at line 1, Create a
PostCSS config module to enable Tailwind v4 processing: add a new module named
postcss.config.mjs in the app to export a config object with a plugins map that
registers the "`@tailwindcss/postcss`" plugin (so the existing `@import`
'tailwindcss' in globals.css is actually processed). Ensure the file exports the
config as the default export and that the plugin key is exactly
"`@tailwindcss/postcss`".
| @@ -0,0 +1,271 @@ | |||
| "use client"; | |||
There was a problem hiding this comment.
Filename casing violation detected - immediate correction required.
Agent, your component file analyzer.tsx must use PascalCase naming. The kit guidelines mandate Analyzer.tsx for React component files in the components/ directory. Rename this file before the mission proceeds.
📁 Mission directive: rename the file
# Rename the file to match PascalCase convention
mv kits/research-paper-analyzer/apps/components/analyzer.tsx \
kits/research-paper-analyzer/apps/components/Analyzer.tsxThe import in page.tsx will continue to work: import { Analyzer } from "@/components/Analyzer";
As per coding guidelines: "Use PascalCase for React component filenames in the components/ directory."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/components/analyzer.tsx` at line 1, Rename
the component file from analyzer.tsx to PascalCase Analyzer.tsx and update any
imports to reference "`@/components/Analyzer`" (e.g., the import in page.tsx that
should be import { Analyzer } from "`@/components/Analyzer`";); ensure the
exported component name (Analyzer) matches the new filename and that no other
imports still reference analyzer.tsx.
| async function handleSubmit(e: React.FormEvent) { | ||
| e.preventDefault(); | ||
| if (!pdfUrl.trim()) return; | ||
| setLoading(true); | ||
| setError(null); | ||
| setResult(null); | ||
| const res = await analyzePaper(pdfUrl.trim()); | ||
| if (res.success && res.data) { | ||
| setResult(res.data); | ||
| } else { | ||
| setError(res.error ?? "Something went wrong."); | ||
| } | ||
| setLoading(false); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff
Consider upgrading form handling to match kit standards.
Agent, your current manual form state management works, but the kit guidelines specify react-hook-form with zod validation for all form handling. While this single-field form could be considered simple, adhering to the established pattern ensures consistency across the kit ecosystem and provides built-in URL validation, error messages, and accessibility features.
📋 Optional mission enhancement: react-hook-form + zod pattern
Install dependencies:
npm install react-hook-form zod `@hookform/resolvers`Example refactor:
import { useForm } from "react-hook-form";
import { zodResolver } from "`@hookform/resolvers/zod`";
import { z } from "zod";
const schema = z.object({
pdfUrl: z.string().url("Please enter a valid URL"),
});
type FormData = z.infer<typeof schema>;
export function Analyzer() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
async function onSubmit(data: FormData) {
setLoading(true);
setError(null);
const res = await analyzePaper(data.pdfUrl);
// ... rest of logic
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("pdfUrl")} type="url" />
{errors.pdfUrl && <span>{errors.pdfUrl.message}</span>}
{/* ... */}
</form>
);
}As per coding guidelines: "Use react-hook-form with zod validation for form handling in kits."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/components/analyzer.tsx` around lines 26 -
39, Replace the manual form state in the Analyzer component (currently using
pdfUrl, handleSubmit, setLoading, setError, setResult and calling analyzePaper)
with react-hook-form and zod validation: define a zod schema for pdfUrl as a
URL, create useForm with zodResolver, move the submission logic into an onSubmit
that receives validated data and calls analyzePaper(data.pdfUrl), and render
form errors from formState.errors instead of manual checks; ensure
loading/error/result state updates remain but are triggered from the useForm
submit handler and the form element uses handleSubmit(onSubmit).
| }, | ||
| "dependencies": { | ||
| "@vercel/analytics": "^1.3.1", | ||
| "lamatic": "latest", |
There was a problem hiding this comment.
Mission critical: Pin the lamatic SDK version immediately.
Agent, the "lamatic": "latest" specifier is a ticking time bomb. Your kit manifest requires pinned dependency versions to ensure reproducible builds and prevent surprise breakage when the upstream SDK ships breaking changes. Replace "latest" with an explicit version (e.g., "1.2.3").
🔒 Proposed fix: pin the version
- "lamatic": "latest",
+ "lamatic": "^1.0.0",(Replace 1.0.0 with the actual current stable version from npm.)
As per coding guidelines: "Each kit must have its own package.json with pinned dependency versions."
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "lamatic": "latest", | |
| "lamatic": "^1.0.0", |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/research-paper-analyzer/apps/package.json` at line 13, The package.json
dependency "lamatic": "latest" must be pinned to a specific version to ensure
reproducible builds; update the "lamatic" entry in apps/package.json to an
explicit semver (e.g., "lamatic": "1.2.3") by looking up the current stable
version on npm, update package-lock.json/yarn.lock via an install (npm install
or yarn install) and commit both package.json and the updated lockfile; ensure
no other dependencies use floating tags.
Replace triggerNode/dynamicNode with the correct Studio-native types: apiTriggerNode, extractFromFileNode, LLMNode, apiResponseNode. Also remove JSON.stringify() calls — use plain objects so Studio can parse the flow without errors. Fixes Phase 2 "flows array must not be empty" validation failure.
|
/validate |
|
📡 Running Studio validation — results will appear here shortly. |
|
/validate |
|
📡 Running Studio validation — results will appear here shortly. |
|
@Suhas-123-cell can you resolve all the coderabbit comments please? |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
kits/research-paper-analyzer— an AI kit that takes any academic PDF URL and returns a structured breakdownfollow-up questions
Core kit & docs
Environment & git
Next.js app (apps/)
Flow definition
Notes from commits/comments (reflected in files)