Skip to content

feat: enhance AI review process and configuration options: - #300

Merged
yashdev9274 merged 2 commits into
mainfrom
supercode-cli
Sep 17, 2026
Merged

yashdev9274 merged 2 commits into
mainfrom
supercode-cli

Conversation

@yashdev9274

@yashdev9274 yashdev9274 commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Description

  • Updated .env.example to clarify embedding provider settings and added debounce configuration for PR review events.
  • Modified the AI review trigger route to support a blocking wait option for manual reviews.
  • Implemented stale pending review detection in the dashboard to improve user experience.
  • Enhanced the review generation process with timing measurements for better performance tracking.
  • Refactored embedding logic to ensure proper provider configuration and error handling.
  • Removed auto-queueing of unreviewed PRs to streamline review management.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactor (no functional changes)

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

  • bun test passes
  • bun run typecheck passes
  • bun run lint passes (if applicable)

Checklist:

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works

Summary by CodeRabbit

  • New Features

    • Added configurable embedding-provider selection and review-event debounce settings.
    • Manual AI reviews now wait for completion and show a completion notification.
    • Stale pending reviews can be restarted after 10 minutes.
  • Bug Fixes

    • Failed synchronous reviews are now recorded as failed.
    • Review status updates refresh reliably after completion.
    • Embedding operations now provide clearer behavior when no provider is configured.
  • Performance

    • GitHub data retrieval and notification processing now run more efficiently.

- Updated .env.example to clarify embedding provider settings and added debounce configuration for PR review events.
- Modified the AI review trigger route to support a blocking wait option for manual reviews.
- Implemented stale pending review detection in the dashboard to improve user experience.
- Enhanced the review generation process with timing measurements for better performance tracking.
- Refactored embedding logic to ensure proper provider configuration and error handling.
- Removed auto-queueing of unreviewed PRs to streamline review management.
@vercel

vercel Bot commented Sep 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
supercli Ready Ready Preview Sep 17, 2026 6:19pm UTC
supercli-client Ready Ready Preview Sep 17, 2026 6:19pm UTC
supercli-docs Ready Ready Preview Sep 17, 2026 6:19pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
vercel-supercodeai-integration Skipped Skipped Sep 17, 2026 6:19pm UTC

@vercel
vercel Bot temporarily deployed to Preview – vercel-supercodeai-integration September 17, 2026 18:11 Inactive
@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 3d796e5d-757a-4567-9489-2b332e7171d9

📥 Commits

Reviewing files that changed from the base of the PR and between 346c1cb and 9d66735.

📒 Files selected for processing (11)
  • apps/web/.env.example
  • apps/web/app/api/reviews/trigger/route.ts
  • apps/web/app/dashboard/pull-requests/[id]/page.tsx
  • apps/web/inngest/functions/ai-review.ts
  • apps/web/lib/gateway.ts
  • apps/web/modules/ai/action/index.ts
  • apps/web/modules/ai/lib/generate-pr-review.ts
  • apps/web/modules/dashboard/actions/index.ts
  • apps/web/modules/github/lib/github.ts
  • apps/web/modules/pinecone/rag/index.ts
  • packages/auth/src/client.ts
 ____________________________________________________________________________________________________________________________________________________________________________
< Good code is its own best documentation. As you're about to add a comment, ask yourself, 'How can I improve the code so that this comment isn't needed?' - Steve McConnell >
 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@yashdev9274

Copy link
Copy Markdown
Owner Author

🤖 Supercode AI Review

Summary

This PR refines the AI review workflow end-to-end: manual review requests can now “wait” for completion, background review runs debounce rapid GitHub synchronize events with a configurable period, and the dashboard treats long-stale pending reviews as recoverable. It also adds timing instrumentation to the review generation pipeline and refactors embeddings provider selection so Pinecone indexing fails fast (or skips) when no valid embedding configuration exists.

Walkthrough

  • Config
    • apps/web/.env.example
      • Documented EMBEDDING_PROVIDER semantics and added PR_REVIEW_DEBOUNCE_SECONDS config.
  • Review triggering / blocking wait
    • apps/web/app/api/reviews/trigger/route.ts
      • Manual trigger now passes { wait: true } into reviewPullRequest(...).
    • apps/web/modules/dashboard/actions/index.ts
      • Server action queueReview now uses { wait: true } and removes the prior auto-queue behavior for unreviewed PRs.
  • Dashboard UX for stale pending
    • apps/web/app/dashboard/pull-requests/[id]/page.tsx
      • Added isStalePending() (10 minutes) and:
        • prevents treating pending as “generating” when stale,
        • shows “generate” UI when stale (or otherwise unfilled/failed).
  • Background debounce
    • apps/web/inngest/functions/ai-review.ts
      • Replaced fixed debounce.period: "30s" with a clamped env-driven value via reviewDebouncePeriod().
  • AI review generation pipeline instrumentation + concurrency
    • apps/web/modules/ai/action/index.ts
      • When options?.wait, wraps runGeneratePrReview in try/catch; on error it calls markReviewFailed(...) then rethrows.
    • apps/web/modules/ai/lib/generate-pr-review.ts
      • Added a measure() helper and logs a timings object at the end.
      • Fetches GitHub PR diff components in parallel via updated github helper (below).
      • Runs Linear notification and email notification concurrently via Promise.all([...]).
  • GitHub diff fetching
    • apps/web/modules/github/lib/github.ts
      • Fetches pulls.get, pulls.listFiles, and pulls.get (diff mediaType) concurrently with Promise.all.
  • Embedding provider correctness
    • apps/web/lib/gateway.ts
      • Added embeddingProvider() that selects vercel | merge | openai | null based on env + key availability.
      • embeddingModel(...) now defaults provider based on embeddingProvider() (falling back to "openai").
    • apps/web/modules/pinecone/rag/index.ts
      • Uses embeddingProvider():
        • generateEmbedding() throws if no provider is configured,
        • indexing/retrieval now short-circuits (warns/returns []) when embedding is unavailable.
  • Auth client URL behavior
    • packages/auth/src/client.ts
      • Removed explicit NEXT_PUBLIC_BETTER_AUTH_URL dependency so Better Auth uses browser origin.

Changes table

File Summary
apps/web/.env.example Documented embedding provider selection and added PR review debounce config.
apps/web/app/api/reviews/trigger/route.ts Manual review trigger now passes wait: true for blocking behavior.
apps/web/app/dashboard/pull-requests/[id]/page.tsx Added stale pending detection (10 min) to change UI/generation behavior.
apps/web/inngest/functions/ai-review.ts Debounce period now derives from PR_REVIEW_DEBOUNCE_SECONDS (clamped 1–30s).
apps/web/lib/gateway.ts Added embeddingProvider() and made embedding model default provider respect env+keys.
apps/web/modules/ai/action/index.ts Improved blocking wait error handling: mark failed then rethrow.
apps/web/modules/ai/lib/generate-pr-review.ts Added stage timing instrumentation; run notifications concurrently.
apps/web/modules/dashboard/actions/index.ts Removed auto-queue unreviewed PRs; queueReview now waits for completion.
apps/web/modules/github/lib/github.ts Fetch PR metadata/files/diff concurrently.
apps/web/modules/pinecone/rag/index.ts Fail/skip embedding operations when no valid provider is configured.
packages/auth/src/client.ts Better Auth no longer requires NEXT_PUBLIC_BETTER_AUTH_URL.

Findings

  • high Stale-pending UI may trigger unintended duplicate review generationapps/web/app/dashboard/pull-requests/[id]/page.tsx
    • You mark isGenerating as false when status === "pending" but stale, and showGenerate becomes true when stalePending is true. However, this page change alone doesn’t guarantee the backend won’t have an in-flight generation already; if the Inngest job finishes just after the user sees “generate”, you could enqueue a duplicate.
    • Suggested fix: ensure the backend reviewPullRequest(...) dedupes by (repositoryId, prNumber) state transitions or adds a “single active job” constraint. If that exists elsewhere, add a comment here indicating dedupe semantics; otherwise consider guarding in the UI by checking for a “job run id”/lock field (if present in your schema).
  • medium Null/empty embedding provider fallback inconsistencyapps/web/lib/gateway.ts and apps/web/modules/pinecone/rag/index.ts
    • embeddingProvider() can return null, and embeddingModel(...) defaults to embeddingProvider() ?? "openai". Meanwhile generateEmbedding() explicitly throws when embeddingProvider() is falsy.
    • This is mostly consistent because generateEmbedding() calls embeddingProvider() first, but other embedding usage paths (if any) could silently fall back to "openai" even when no key exists.
    • Suggested fix: change embeddingModel default to require an explicit provider (or throw when embeddingProvider() is null), so failures are uniform across call sites.
  • medium Timings logging could leak sensitive metadataapps/web/modules/ai/lib/generate-pr-review.ts
    • You log repoId#prNumber and a full timings JSON. That’s probably safe, but console.log at high volume can get noisy; plus stage names could become a debugging vector.
    • Suggested fix: consider gating this log behind an env flag (e.g., DEBUG_AI_TIMINGS) or logging only when a debug mode is enabled.
  • nit Debounce env parsing typeapps/web/inngest/functions/ai-review.ts
    • reviewDebouncePeriod(): \${number}s`is fine, and you clamp to 1–30 seconds. Minor nit: theNumber.isFinite(configured)check is good, but consider handling0` explicitly (currently it becomes 5 due to clamp; that’s okay).

Risk assessment

Medium — This touches core workflow control flow (blocking waits), removes auto-queueing (behavioral change), and changes embedding provider selection. Blast radius is mainly in review generation + dashboard UX + embeddings/RAG availability.

Test plan

  • Run unit/integration tests if present: bun test
  • Typecheck: bun run typecheck
  • Lint: bun run lint
  • Manual: Trigger /api/reviews/trigger for a connected repo and verify the request blocks until completion and returns the expected “Review completed” response
  • Manual: Use dashboard “queue review” and confirm the server action now waits (no “row stays pending” due to response callbacks)
  • Manual: On a PR, force a pending review older than 10 minutes and verify UI shows “generate” again instead of indefinitely showing “generating”
  • Manual/staging: Set EMBEDDING_PROVIDER to an invalid value and ensure Pinecone indexing logs the skip/warn and does not crash indexing jobs
  • Manual: Verify debounce works by sending rapid synchronize events and confirming only one latest-head review is produced within the configured window

Suggested PR description

What

  • Added configurable debounce for background AI PR review events.
  • Enabled a blocking “wait” mode for manual and dashboard-triggered review runs.
  • Added stale pending detection (10 minutes) in the PR review detail page to improve recovery UX.
  • Refactored embeddings provider selection and improved error handling for Pinecone embedding generation.
  • Removed auto-queueing of unreviewed PRs in the dashboard list.

Why

  • Prevents stampedes from rapid GitHub synchronize events and gives consistent user feedback.
  • Fixes cases where server-side queueing could leave rows stuck in pending due to post-response interruptions.
  • Avoids embedding/provider misconfiguration issues (especially around Vercel free-tier model rejection).
  • Improves observability of review pipeline performance.

How tested

  • bun test
  • bun run typecheck
  • bun run lint
  • Verified manually:
    • blocking behavior for /api/reviews/trigger and dashboard queue action
    • stale-pending UI behavior on an artificially aged review
    • embedding provider misconfiguration behavior (skip/fail fast) in Pinecone RAG flows

Automated review by Supercode · leave a 👍/👎 reaction to rate this review

const result = await reviewPullRequest(owner, repo, prNumber, {
userId: session.user.id,
source: "api_trigger",
wait: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now blocks the HTTP request until the full LLM pipeline finishes. Unlike the Inngest route, this route doesn't export maxDuration, so on Vercel the request can hit the function timeout and return a 500/504 even though the review eventually completes (the caller just never sees the result). Consider raising maxDuration here or making the blocking behavior opt-in via a query param.

Comment thread apps/web/lib/gateway.ts
export function embeddingModel(
modelId: string,
provider: GatewayProviderName = activeGatewayProvider,
provider: "vercel" | "merge" | "openai" = embeddingProvider() ?? "openai",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ?? "openai" fallback bypasses the key checks in embeddingProvider(), so any caller that omits provider will attempt direct OpenAI even with no key configured — exactly what the new guard is meant to prevent. The only caller passes it explicitly now, so the default can just go away:

Suggested change
provider: "vercel" | "merge" | "openai" = embeddingProvider() ?? "openai",
provider: "vercel" | "merge" | "openai",

}
} catch (error) {
const message = error instanceof Error ? error.message : "Unknown Error"
await markReviewFailed(payload, message)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If markReviewFailed itself throws (e.g. DB hiccup), it replaces the original review error and you lose the real failure reason. Keeping it best-effort preserves the root cause:

Suggested change
await markReviewFailed(payload, message)
await markReviewFailed(payload, message).catch(() => {})

const result = await reviewPullRequest(owner, repo, prNumber, {
userId: session.user.id,
source: "dashboard",
wait: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking the server action works, but if the platform kills it at the execution limit the client gets an error and the row sits pending until the 10-minute stale threshold flips it back — that's a long spinner for the user. Might be worth surfacing stale state sooner than 10 min, or letting the stale threshold account for reviews that are genuinely long-running.

@greptile-apps

greptile-apps Bot commented Sep 17, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 3/5

This PR is not yet safe to merge because blocking review execution can exceed request lifetimes, and stale-pending retries can race with active reviews and overwrite newer output.

Findings

  1. P1 Blocking reviews can time out
  2. P1 Stale retries can overwrite reviews
  3. P2 Failure handling masks errors
  4. P2 Auth setup documentation is stale
  5. P2 Failed runs lose timings

Summary

This PR changes manual AI review execution to block until completion, introduces stale-pending recovery and pipeline timing, parallelizes independent network work, makes embedding-provider selection explicit, removes automatic review queueing, and makes browser authentication use the current origin.

  • Manual dashboard and API review requests now execute the complete review pipeline inline.
  • Pending reviews older than ten minutes can be manually retried.
  • Review stages are timed, and Linear/email notifications plus GitHub metadata requests run concurrently.
  • RAG indexing and retrieval now require an explicitly usable embedding provider or a direct OpenAI key.
  • Dashboard listing no longer automatically queues unreviewed pull requests.
  • The shared auth client now targets each application's current origin.

Diagram

sequenceDiagram
  actor User
  participant UI as Dashboard / Trigger API
  participant Action as reviewPullRequest
  participant DB as Review DB
  participant Pipeline as runGeneratePrReview
  participant GitHub
  participant AI as Embedding + LLM
  participant Notify as Linear + Email

  User->>UI: Generate review
  UI->>Action: wait: true
  Action->>DB: "status = pending"
  Action->>Pipeline: await review pipeline
  Pipeline->>GitHub: Fetch PR, files, and diff
  Pipeline->>AI: Retrieve context and generate review
  Pipeline->>DB: "status = completed, save review"
  Pipeline->>GitHub: Update sticky comment
  par Notifications
    Pipeline->>Notify: Notify Linear
  and
    Pipeline->>Notify: Send email
  end
  Pipeline-->>Action: Result
  Action-->>UI: Review completed
Loading

Reviews (1) · Last reviewed commit: "feat: enhance AI review process and conf..."

const result = await reviewPullRequest(owner, repo, prNumber, {
userId: session.user.id,
source: "dashboard",
wait: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Blocking reviews can time out

This makes the dashboard action wait for the full GitHub, Pinecone, model-generation, persistence, commenting, and notification pipeline. The same blocking behavior also occurs in apps/web/app/api/reviews/trigger/route.ts:52. If a review exceeds the hosting platform's request limit, the process can be terminated before markReviewFailed runs. The client then receives an error while the review remains pending. Keep this work in the background worker, or give every blocking entry point enough execution time and durable timeout recovery.

Comment on lines 120 to +123
!isGenerating &&
(review.status === "unreviewed" ||
review.status === "failed" ||
stalePending ||

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Stale retries can overwrite reviews

A pending review older than ten minutes may still be running because there is no heartbeat. This condition enables another review without checking for an active run, and direct execution does not share Inngest's per-PR concurrency control. Both runs can then update the same database row and sticky GitHub comment, allowing an older run that finishes last to overwrite newer output. Recovery should verify that no run is active or reject results from obsolete runs or head SHAs.

Comment on lines +170 to +174
}
} catch (error) {
const message = error instanceof Error ? error.message : "Unknown Error"
await markReviewFailed(payload, message)
throw error

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Failure handling masks errors

This catch awaits markReviewFailed before rethrowing the original generation error. If that database write fails, its error replaces the actual review failure. If it succeeds, the rethrown error reaches the existing outer catch, which records the same failure again. Preserve the original exception and use one guarded failure-recording path.

Comment on lines +4 to +6
// browser's current origin so local, preview, and production deployments do
// not depend on a separately configured public URL.
export const { signIn, signUp, useSession, signOut } = createAuthClient();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Auth setup documentation is stale

The client no longer reads NEXT_PUBLIC_BETTER_AUTH_URL, but AGENTS.md:111 still lists that variable as required. Update the documented environment contract so developers are not instructed to configure an ineffective variable.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

- Added functionality to extract and update PR description summaries during review generation.
- Implemented concurrent processing for posting review comments and updating PR summaries to improve efficiency.
- Introduced new constants and helper functions for managing PR summary formatting and merging.
const result = await reviewPullRequest(owner, repo, prNumber, {
userId: session.user.id,
source: "api_trigger",
wait: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The blocking /api/reviews/trigger route lacks export const maxDuration, so long reviews hit the Vercel default function timeout and return 500/504.

Fix on Vercel

@yashdev9274
yashdev9274 merged commit 8ee7f07 into main Sep 17, 2026
6 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant