feat: add Agentic AI Contribution Recommender Engine (Issue #611)#614
Conversation
❌ Deploy Preview for github-spy failed.
|
|
Warning Review limit reached
More reviews will be available in 34 minutes and 50 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThis PR introduces an AI-powered contribution recommender that analyzes a GitHub user's coding patterns and recommends open-source issues they are best positioned to contribute to. It builds a skill profile from public repositories, scouts matching issues via GitHub API searches, ranks them by relevance, and displays the top 3 through an interactive animated component integrated into the Tracker dashboard. ChangesAI Contribution Recommender
Sequence DiagramsequenceDiagram
participant User as User / Tracker
participant Component as ContributionRecommender
participant Hook as useContributionRecommender
participant GitHub as GitHub API
User->>Component: Mount with username + getOctokit
Component->>Hook: runRecommender(username)
Note over Hook: agentStep = "building-profile"
Hook->>GitHub: Fetch user repositories
GitHub-->>Hook: Repos (languages, stars, recency)
Note over Hook: agentStep = "scouting-issues"
Hook->>GitHub: Search good-first-issue + help-wanted<br/>(across top languages)
GitHub-->>Hook: Candidate issues
Note over Hook: agentStep = "ranking-matches"
Hook->>GitHub: Fetch repository metadata for candidates
GitHub-->>Hook: Repo data (stars, owner, etc.)
Hook->>Hook: Compute match scores & rank
Hook-->>Component: recommendations[], skillProfile, agentStep
Component->>Component: Render skill profile + results list
Component->>User: Display top 3 recommendations
User->>Component: Click refresh button
Component->>Hook: runRecommender(username, force=true)
Hook-->>Component: Updated recommendations
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 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 |
…sLab#611) - Add useContributionRecommender hook with 3-step agentic pipeline: * Step 1 (Skill Profiler): fetches user repos, detects top languages weighted by recency and stars, infers domain (frontend/backend/devops) * Step 2 (Issue Scout): searches GitHub for open issues tagged 'good first issue' or 'help wanted' matching top languages, using Promise.allSettled for non-blocking async parallelism * Step 3 (Relevance Ranker): scores issues by language rank, label quality, repo star count, and recency; returns top 3 - Add ContributionRecommender.tsx widget with premium glassmorphism UI: * Gradient accent bar and indigo/sky branded header with Sparkles icon * Skill profile badge row showing detected languages + activity level * Loading state with animated 3-step progress bar and shimmer skeleton * Framer-motion stagger animations on recommendation cards * Each card: repo name, star count, issue title, 'Why this matches you' reasoning box, labels, difficulty badge (Beginner/Intermediate), CTA * Error/empty states with retry button * Session-level caching via useRef to avoid redundant API calls * Refresh button to force re-run - Integrate widget into Tracker.tsx below DailyActivityStatus - Add @Keyframes recommender-pulse and recommender-shimmer to index.css - Document future GITHUB_SERVER_TOKEN env var in backend/.env.example Closes GitMetricsLab#611
de48013 to
37ef3a6
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@src/hooks/useContributionRecommender.ts`:
- Around line 139-149: The current scoutIssues implementation maps queries to
octokit.request calls but swallows every request error with .catch(() => []), so
Promise.allSettled never sees rejections; remove the per-request .catch on the
octokit.request in the searchRequests creation inside useContributionRecommender
(the mapped call that builds searchRequests) and instead await
Promise.allSettled(searchRequests) in scoutIssues/runRecommender, inspect each
settled result (status === 'fulfilled' collect value, status === 'rejected'
collect errors), and if all are rejected throw one of the errors (or a composed
error) to surface auth/rate-limit/validation failures to the outer try/catch; if
some are fulfilled, use those partial results (combine fulfilled values) rather
than treating a mixed outcome as an empty result.
- Around line 329-409: The runRecommender pipeline can be overwritten by slower,
earlier runs; add a run guard (request id or AbortController) inside
runRecommender to ignore stale results: create a local runId (or controller) at
the start of runRecommender, store it in a ref (e.g., currentRunRef), and check
it before setting state and before caching (references: runRecommender,
cacheRef, setSkillProfile, setRecommendations, setRecommenderError,
setRecommenderLoading, setAgentStep); ensure any async branches return early if
the runId no longer matches (or if the controller is aborted) so only the latest
invocation updates state and cache.
- Around line 126-167: scoutIssues currently returns only GitHubSearchIssue[]
which loses the query language; modify scoutIssues to carry the original query
language and computed langRank through to ranking (either return an array of {
issue, matchedLanguage, langRank } or build and return a Map keyed by issue.id
with {matchedLanguage, langRank}), ensure you de-duplicate by keeping the lowest
langRank when an issue appears in multiple queries, and update
rankIssues/scoreIssue/computeMatchReason to read matchedLanguage/langRank from
the new structure instead of inferring from labels (use
skillProfile.topLanguages to compute langRank consistently).
- Around line 121-123: The buildSearchQuery function is incorrectly replacing
spaces inside quoted labels and omitting the is:issue filter; update
buildSearchQuery(language: string, label: string) to keep the label verbatim
inside the quotes (do not replace spaces with '+') and include the is:issue
token in the returned query string (e.g., add +is:issue) so the GET
/search/issues request only returns issues; refer to the buildSearchQuery
function to make this change.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4d62833f-3c33-4e04-8d9b-3e43b08b5a75
📒 Files selected for processing (5)
backend/.env.examplesrc/components/ContributionRecommender.tsxsrc/hooks/useContributionRecommender.tssrc/index.csssrc/pages/Tracker/Tracker.tsx
- Fix search query construction to preserve spaces and include is:issue - Preserve language query context from scout to ranker to avoid inaccurate inference - Throw error on all search queries failing to properly bubble up rate limit / auth errors - Add requestId guard in runRecommender to prevent stale concurrent runs - Remove unused DailyActivityStatus and Backtotop imports from Tracker.tsx
|
hi @mehul-m-prajapati , |
|
🎉🎉 Thank you for your contribution! Your PR #614 has been merged! 🎉🎉 |
Related Issue
Description
Implements the Agentic AI Contribution Recommender Engine proposed in Issue #611.
Instead of a Python microservice (optional future follow-up), this PR delivers a fully client-side, three-step agentic pipeline that runs in the browser using the user's own GitHub token — keeping the PR self-contained with zero backend changes required.
🧠 Architecture: Multi-Step Agentic Pipeline
[Step 1] Skill Profiler → GET /users/{username}/repos → Scores languages weighted by recency + star count → Infers domains: frontend / backend / devops / mobile / data → Determines activity level: high / medium / low
[Step 2] Issue Scout (non-blocking, Promise.allSettled) → Parallel GitHub Search API queries: top 3 languages × ["good first issue", "help wanted"] → Deduplicates results across all queries
[Step 3] Relevance Ranker → Scores each issue: language rank ×30, label quality ×25, star count ×0.1, recency ×20 → Fetches repo metadata for top 15 candidates → Returns top 3 ranked recommendations
✨ New Files
src/hooks/useContributionRecommender.ts— core agentic pipeline hook with session-level caching (useRef) to avoid redundant API callssrc/components/ContributionRecommender.tsx— premium glassmorphism widget featuring:🔧 Modified Files
src/pages/Tracker/Tracker.tsx— integrates widget belowDailyActivityStatus, auto-triggers on username submitsrc/index.css— adds@keyframes recommender-pulse(activity dot) and@keyframes recommender-shimmer(loading skeleton)backend/.env.example— documents futureGITHUB_SERVER_TOKENfor the optional Python microservice follow-upHow Has This Been Tested?
/track, entered a GitHub username (with and without a PAT)npm run build— ✓ 3027 modules transformed, zero TypeScript errors, built in 21sScreenshots (if applicable)
Type of Change
Summary by CodeRabbit
New Features
Chores