Skip to content

Week 4 project update#2

Open
kushal281 wants to merge 5 commits into
OpenLake:mainfrom
kushal281:main
Open

Week 4 project update#2
kushal281 wants to merge 5 commits into
OpenLake:mainfrom
kushal281:main

Conversation

@kushal281

@kushal281 kushal281 commented Jun 25, 2026

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features
    • Added a GitHub webhook that checks newly opened issues for potential duplicates and posts a comment when a close match is found.
    • Added issue ingestion and similarity search to store and compare issue content.
    • Added a /health endpoint for service monitoring.
  • Bug Fixes
    • Webhook requests are now authenticated and validated; malformed payloads are rejected and ping requests are handled explicitly.
  • Documentation
    • Updated README formatting for the troubleshooting and API overview sections.
  • Chores
    • Added environment variable examples and improved ignore rules for local/editor/database artifacts.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kushal281, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ae6dbbc7-bd08-4b35-bae7-a3d31a5c08b5

📥 Commits

Reviewing files that changed from the base of the PR and between c02652f and 333f78c.

📒 Files selected for processing (3)
  • README.md
  • app/config.py
  • app/db/ingest.py

Walkthrough

The PR adds GitHub setup files, configuration loading, GitHub API access, embeddings and vector search, issue cleaning and duplicate detection, ingestion, and webhook processing. It also mounts the FastAPI app and adds a health endpoint.

Changes

Repository setup

Layer / File(s) Summary
Environment and ignore defaults
.env.example, .gitignore
Adds GitHub env placeholders and ignore rules for Python artifacts, virtualenvs, .env, Chroma data, IDE folders, and .DS_Store.
README edits
README.md
Updates the table of contents entry, reformats the API overview table, and appends merge-conflict markers at the end of the README.

GitHub triage flow

Layer / File(s) Summary
Config and GitHub client
app/config.py, app/core/github.py
Loads environment variables into configuration constants and uses them to construct the GitHub client wrapper for repository lookup, issue fetching, and commenting.
Embedding and vector search
app/ml/embedder.py, app/db/vector.py, app/test.py
Adds the sentence transformer embedder, ChromaDB issue collection helpers, and a small similarity-search script.
Issue cleaning and duplicate detection
app/ml/clean.py, app/ml/duplicate.py
Builds cleaned issue text and embeddings, then compares them against the configured similarity threshold.
Ingestion and app bootstrap
app/db/ingest.py, app/main.py
Writes cleaned issues to ChromaDB and JSON, then mounts the webhook router and exposes a health endpoint.
Webhook processing
app/api/webhooks.py
Verifies GitHub webhook signatures, handles ping events, checks opened issues for duplicates, and comments on matches.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHub
  participant github_webhook
  participant detect_duplicate
  participant search_similar_issue
  participant GitHubClient
  participant GitHubAPI
  GitHub->>github_webhook: POST /webhook issues opened event
  github_webhook->>detect_duplicate: title and body text
  detect_duplicate->>search_similar_issue: embedding
  search_similar_issue-->>detect_duplicate: distances and metadata
  detect_duplicate-->>github_webhook: duplicate result
  github_webhook->>GitHubClient: comment_issue(issue_number, comment)
  GitHubClient->>GitHubAPI: create issue comment
Loading

Poem

A bunny hopped through hooks with glee,
And tucked embeddings in the tree.
If issues look the same to me,
I’ll leave a comment, quick and wee.
Thump-thump! 🐇

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and does not describe the main change in the pull request. Use a specific title that names the core feature, such as GitHub webhook-based duplicate issue triage or issue ingestion improvements.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (7)
.gitignore (1)

9-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Ignore the whole Chroma data directory, not one generated file.

This is brittle: a new Chroma persistence file or regenerated collection ID will fall back into the repo. Ignoring data/chroma/ keeps the local DB out of source control without depending on a specific UUID.

♻️ Suggested cleanup
 # Chroma database
 data/issues.json
-data/chroma/chroma.sqlite3
-data/chroma/defcbcc9-4578-4553-b3f4-648cbe1c763b
+data/chroma/

As per the app/db/vector.py snippet, Chroma persists under ./data/chroma.

🤖 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 @.gitignore around lines 9 - 12, The .gitignore entry is too specific because
it only excludes individual Chroma-generated files instead of the whole
persistence directory. Update the Chroma ignore rules to cover the entire
data/chroma folder so any files created by the vector store, including future
collection IDs or sqlite artifacts from app/db/vector.py and the Chroma
persistence path under ./data/chroma, stay out of source control.
app/db/ingest.py (1)

13-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Misleading variable name.

uncleaned_issues holds the raw issue records persisted to data/issues.json; a name like raw_issues would read more clearly. Cosmetic only.

🤖 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 `@app/db/ingest.py` at line 13, The variable name in the ingestion logic is
misleading because `uncleaned_issues` actually stores the raw issue records
loaded from and persisted to `data/issues.json`. Rename it to something clearer
like `raw_issues` in the `ingest` flow so the intent is obvious, and update any
nearby references in the same scope to match.
app/core/github.py (2)

39-42: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use a local variable instead of self.repo.

Assigning to self.repo introduces mutable per-call instance state that other methods could accidentally depend on. A local variable is clearer and side-effect free.

♻️ Proposed change
     def comment_issue(self, issue_number, comment):
-        self.repo = self.get_repo(TARGET_REPO)
-        issue = self.repo.get_issue(number=issue_number)
+        repo = self.get_repo(TARGET_REPO)
+        issue = repo.get_issue(number=issue_number)
         issue.create_comment(comment)
🤖 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 `@app/core/github.py` around lines 39 - 42, Replace the mutable instance
assignment in comment_issue with a local repository variable instead of setting
self.repo. In github.py, update comment_issue to store the result of
get_repo(TARGET_REPO) in a local name and use that for get_issue/create_comment,
keeping the method side-effect free and avoiding accidental reliance on shared
instance state.

15-37: 🩺 Stability & Availability | 🔵 Trivial | ⚖️ Poor tradeoff

Add error handling around external GitHub calls.

get_repo, get_issues, and create_comment can raise on rate limits, network errors, or auth failures. In the webhook path these are invoked on a request thread; unhandled exceptions will surface as 500s with no recovery. Consider wrapping calls with structured error handling and respecting PyGithub's rate-limit/retry options.

🤖 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 `@app/core/github.py` around lines 15 - 37, Add structured error handling
around the external GitHub API calls in the GitHub integration so request-thread
failures don’t escape as unhandled 500s. In the methods that call PyGithub,
especially fetch_issues, and anywhere create_comment is used, wrap get_repo,
get_issues, and comment creation in a try/except that catches
GitHub/PyGithub/network/rate-limit/auth failures and returns a controlled error
or logs context. Use the existing GitHub class methods as the place to
centralize this, and ensure the webhook path handles these failures gracefully
instead of propagating exceptions.
app/ml/clean.py (1)

3-3: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Module-level Embedder() loads the model at import time.

Instantiating the SentenceTransformer at import means any module importing clean_issue (ingest script, webhook handler, tests) pays the model-load cost eagerly, even when no embedding is needed. Consider lazy initialization or dependency injection.

🤖 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 `@app/ml/clean.py` at line 3, Module-level instantiation of Embedder is loading
the SentenceTransformer eagerly on import, so move this initialization out of
the top level in clean_issue/clean.py. Refactor Embedder usage to support lazy
creation or dependency injection, and update the callers that use embedder so
the model is only loaded when embedding is actually needed.
app/config.py (1)

6-10: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider failing fast on missing required configuration.

GITHUB_TOKEN, TARGET_REPO, and SOURCE_REPO will silently be None if unset, surfacing later as confusing runtime errors deep in the GitHub client. A startup check would make misconfiguration obvious.

🤖 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 `@app/config.py` around lines 6 - 10, Fail fast on missing required
configuration in app/config.py by validating the module-level settings for
GITHUB_TOKEN, TARGET_REPO, and SOURCE_REPO as soon as they are loaded instead of
leaving them as None. Update the config initialization around WEBHOOK_SECRET,
GITHUB_TOKEN, TARGET_REPO, SIMILARITY_THRESHOLD, and SOURCE_REPO so missing
required values raise an immediate startup error with a clear message, and keep
SIMILARITY_THRESHOLD parsing unchanged except for any needed validation.
app/ml/embedder.py (1)

3-9: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoff

Consider caching/sharing a single Embedder instance.

SentenceTransformer("all-MiniLM-L6-v2") is loaded on every Embedder() construction. Since duplicate.py, test.py, and ingestion each instantiate their own, the model is loaded multiple times in a process. Reusing a module-level singleton avoids redundant load time and memory.

🤖 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 `@app/ml/embedder.py` around lines 3 - 9, The Embedder class currently loads
SentenceTransformer("all-MiniLM-L6-v2") in every __init__ call, causing
redundant model loads across duplicate.py, test.py, and ingestion. Refactor
Embedder so the SentenceTransformer instance is created once and shared, ideally
via a module-level singleton or cached factory used by Embedder.__init__ and
generate_embedding, and update the call sites to reuse the same Embedder
instance instead of constructing new ones repeatedly.
🤖 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 @.env.example:
- Around line 1-11: The env example is inconsistent with the real config
contract and duplicates keys, so clean up the file to show one canonical set of
variables only. Update the example to match what app/config.py reads by
documenting GITHUB_WEBHOOK_SECRET, GITHUB_TOKEN, TARGET_REPO,
SIMILARITY_THRESHOLD, and SOURCE_REPO, and remove the conflicting
REPO_NAME/MY_REPO_NAME block so contributors see a single unambiguous template.

In `@app/api/webhooks.py`:
- Around line 10-21: The github_webhook handler currently accepts any POST
request without verifying the GitHub HMAC signature. In github_webhook, read the
raw request body first, compute the expected X-Hub-Signature-256 using the
configured webhook secret, and compare it with the incoming header using a
constant-time check before parsing the payload. If the signature is missing or
invalid, return an unauthorized response and only proceed with event processing
after the signature is validated.
- Around line 27-31: Guard against malformed issue payloads in the webhook
handler by updating the `issue_text` construction in `app/api/webhooks.py` to
use safe accessors instead of direct indexing on `payload["issue"]["title"]`;
validate the payload shape first, return early for missing `issue` or `title`,
and keep the existing flow in the webhook parsing logic so bad
attacker-controlled input cannot raise a `KeyError` and trigger a 500.
- Around line 33-49: The async webhook handler is calling blocking work
directly, which can stall the event loop and hurt concurrency; in the webhook
flow around detect_duplicate and github.comment_issue, move both the duplicate
detection and the PyGithub issue comment call off the event loop using a
threadpool or background task. Update the handler in app/api/webhooks.py so the
logic around detect_duplicate(payload["issue"]["body"]) and
github.comment_issue(...) is awaited through an async-safe offload path, keeping
the async request handler non-blocking.

In `@app/config.py`:
- Line 6: The webhook flow currently reads WEBHOOK_SECRET in app/config.py but
the handler in app/api/webhooks.py does not use it to authenticate incoming
requests. Update the /webhook handling logic to verify GitHub’s
X-Hub-Signature-256 against an HMAC-SHA256 computed from the raw request body
using WEBHOOK_SECRET, and reject requests when the signature is missing or
invalid before any parsing or duplicate-detection work runs. Use the webhook
handler entrypoint and request-processing logic in app/api/webhooks.py to locate
the change, and perform the comparison in constant time.

In `@app/db/vector.py`:
- Line 7: The collection created in client.get_or_create_collection for
github_issues is using the default L2 distance, which breaks the similarity math
used by app.ml.duplicate's similarity calculation. Update the collection
creation in app.db.vector so github_issues is created with an explicit cosine
distance metric/space, keeping the returned distances compatible with max(0, 1 -
distance).

In `@app/test.py`:
- Around line 2-16: The test is importing and calling the wrong vector search
helper: `app.db.vector` exposes `search_similar_issue`, not `search_similar`.
Update the import in `app/test.py` to use the सही function name, and adjust the
call site to invoke `search_similar_issue` with the embedding so the test
matches the actual API.

In `@README.md`:
- Around line 1-4: The README is still left with merge-conflict markers, so
remove the conflict artifacts and keep the intended content only. Clean up both
conflicted sections in README.md by deleting the HEAD/divider markers and
retaining the final README text, using the visible conflict blocks near the top
and bottom of the file as the locations to fix.

---

Nitpick comments:
In @.gitignore:
- Around line 9-12: The .gitignore entry is too specific because it only
excludes individual Chroma-generated files instead of the whole persistence
directory. Update the Chroma ignore rules to cover the entire data/chroma folder
so any files created by the vector store, including future collection IDs or
sqlite artifacts from app/db/vector.py and the Chroma persistence path under
./data/chroma, stay out of source control.

In `@app/config.py`:
- Around line 6-10: Fail fast on missing required configuration in app/config.py
by validating the module-level settings for GITHUB_TOKEN, TARGET_REPO, and
SOURCE_REPO as soon as they are loaded instead of leaving them as None. Update
the config initialization around WEBHOOK_SECRET, GITHUB_TOKEN, TARGET_REPO,
SIMILARITY_THRESHOLD, and SOURCE_REPO so missing required values raise an
immediate startup error with a clear message, and keep SIMILARITY_THRESHOLD
parsing unchanged except for any needed validation.

In `@app/core/github.py`:
- Around line 39-42: Replace the mutable instance assignment in comment_issue
with a local repository variable instead of setting self.repo. In github.py,
update comment_issue to store the result of get_repo(TARGET_REPO) in a local
name and use that for get_issue/create_comment, keeping the method side-effect
free and avoiding accidental reliance on shared instance state.
- Around line 15-37: Add structured error handling around the external GitHub
API calls in the GitHub integration so request-thread failures don’t escape as
unhandled 500s. In the methods that call PyGithub, especially fetch_issues, and
anywhere create_comment is used, wrap get_repo, get_issues, and comment creation
in a try/except that catches GitHub/PyGithub/network/rate-limit/auth failures
and returns a controlled error or logs context. Use the existing GitHub class
methods as the place to centralize this, and ensure the webhook path handles
these failures gracefully instead of propagating exceptions.

In `@app/db/ingest.py`:
- Line 13: The variable name in the ingestion logic is misleading because
`uncleaned_issues` actually stores the raw issue records loaded from and
persisted to `data/issues.json`. Rename it to something clearer like
`raw_issues` in the `ingest` flow so the intent is obvious, and update any
nearby references in the same scope to match.

In `@app/ml/clean.py`:
- Line 3: Module-level instantiation of Embedder is loading the
SentenceTransformer eagerly on import, so move this initialization out of the
top level in clean_issue/clean.py. Refactor Embedder usage to support lazy
creation or dependency injection, and update the callers that use embedder so
the model is only loaded when embedding is actually needed.

In `@app/ml/embedder.py`:
- Around line 3-9: The Embedder class currently loads
SentenceTransformer("all-MiniLM-L6-v2") in every __init__ call, causing
redundant model loads across duplicate.py, test.py, and ingestion. Refactor
Embedder so the SentenceTransformer instance is created once and shared, ideally
via a module-level singleton or cached factory used by Embedder.__init__ and
generate_embedding, and update the call sites to reuse the same Embedder
instance instead of constructing new ones repeatedly.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3e1bbede-441c-4408-a2d0-3cb0a21af05d

📥 Commits

Reviewing files that changed from the base of the PR and between c703023 and b86ddae.

📒 Files selected for processing (14)
  • .env.example
  • .gitignore
  • README.md
  • app/api/webhooks.py
  • app/config.py
  • app/core/github.py
  • app/db/ingest.py
  • app/db/vector.py
  • app/main.py
  • app/ml/clean.py
  • app/ml/duplicate.py
  • app/ml/embedder.py
  • app/test.py
  • requirements.txt

Comment thread .env.example Outdated
Comment on lines +1 to +11
GITHUB_WEBHOOK_SECRET=
GITHUB_TOKEN=
REPO_NAME= #Enter repo from where you want to fetch issues
SIMILARITY_THRESHOLD=
MY_REPO_NAME= #Enter repo for which you want to use

GITHUB_TOKEN=your_token_here
GITHUB_WEBHOOK_SECRET=your_secret_here
REPO_NAME=OpenLake/your-repo
TARGET_REPO=your-test-repo
SIMILARITY_THRESHOLD=0.85 No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Align the example with the actual env contract.

This file has two conflicting key blocks, and it never documents SOURCE_REPO, which app/config.py reads. New contributors will copy an incomplete/ambiguous config.

♻️ Suggested cleanup
-GITHUB_WEBHOOK_SECRET=
-GITHUB_TOKEN=
-REPO_NAME= `#Enter` repo from where you want to fetch issues
-SIMILARITY_THRESHOLD=
-MY_REPO_NAME= `#Enter` repo for which you want to use 
-
 GITHUB_TOKEN=your_token_here
 GITHUB_WEBHOOK_SECRET=your_secret_here
-REPO_NAME=OpenLake/your-repo
+SOURCE_REPO=OpenLake/your-repo
 TARGET_REPO=your-test-repo
 SIMILARITY_THRESHOLD=0.85

As per the app/config.py snippet, the app loads GITHUB_WEBHOOK_SECRET, GITHUB_TOKEN, TARGET_REPO, SIMILARITY_THRESHOLD, and SOURCE_REPO.

📝 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.

Suggested change
GITHUB_WEBHOOK_SECRET=
GITHUB_TOKEN=
REPO_NAME= #Enter repo from where you want to fetch issues
SIMILARITY_THRESHOLD=
MY_REPO_NAME= #Enter repo for which you want to use
GITHUB_TOKEN=your_token_here
GITHUB_WEBHOOK_SECRET=your_secret_here
REPO_NAME=OpenLake/your-repo
TARGET_REPO=your-test-repo
SIMILARITY_THRESHOLD=0.85
GITHUB_TOKEN=your_token_here
GITHUB_WEBHOOK_SECRET=your_secret_here
SOURCE_REPO=OpenLake/your-repo
TARGET_REPO=your-test-repo
SIMILARITY_THRESHOLD=0.85
🧰 Tools
🪛 dotenv-linter (4.0.0)

[warning] 2-2: [UnorderedKey] The GITHUB_TOKEN key should go before the GITHUB_WEBHOOK_SECRET key

(UnorderedKey)


[warning] 3-3: [SpaceCharacter] The line has spaces around equal sign

(SpaceCharacter)


[warning] 3-3: [ValueWithoutQuotes] This value needs to be surrounded in quotes

(ValueWithoutQuotes)


[warning] 5-5: [SpaceCharacter] The line has spaces around equal sign

(SpaceCharacter)


[warning] 5-5: [TrailingWhitespace] Trailing whitespace detected

(TrailingWhitespace)


[warning] 5-5: [UnorderedKey] The MY_REPO_NAME key should go before the REPO_NAME key

(UnorderedKey)


[warning] 5-5: [ValueWithoutQuotes] This value needs to be surrounded in quotes

(ValueWithoutQuotes)


[warning] 7-7: [DuplicatedKey] The GITHUB_TOKEN key is duplicated

(DuplicatedKey)


[warning] 8-8: [DuplicatedKey] The GITHUB_WEBHOOK_SECRET key is duplicated

(DuplicatedKey)


[warning] 9-9: [DuplicatedKey] The REPO_NAME key is duplicated

(DuplicatedKey)


[warning] 11-11: [DuplicatedKey] The SIMILARITY_THRESHOLD key is duplicated

(DuplicatedKey)


[warning] 11-11: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 11-11: [UnorderedKey] The SIMILARITY_THRESHOLD key should go before the TARGET_REPO 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 @.env.example around lines 1 - 11, The env example is inconsistent with the
real config contract and duplicates keys, so clean up the file to show one
canonical set of variables only. Update the example to match what app/config.py
reads by documenting GITHUB_WEBHOOK_SECRET, GITHUB_TOKEN, TARGET_REPO,
SIMILARITY_THRESHOLD, and SOURCE_REPO, and remove the conflicting
REPO_NAME/MY_REPO_NAME block so contributors see a single unambiguous template.

Comment thread app/api/webhooks.py
Comment thread app/api/webhooks.py Outdated
Comment thread app/api/webhooks.py Outdated
Comment on lines +33 to +49
result = detect_duplicate(issue_text)
print("Duplicate result:", result)

if result and result["duplicate"]:
github.comment_issue(
payload["issue"]["number"],

f"""
Possible duplicate issue detected.

Similar issue:
{result['issue']['url']}

Similarity:
{result['similarity']:.2f}
"""
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Blocking work runs on the event loop.

detect_duplicate (model encode + Chroma query) and github.comment_issue (synchronous PyGithub HTTP calls) are blocking, but this is an async handler. They will stall the event loop and degrade concurrency under load. Offload to a thread (e.g. await run_in_threadpool(...)) or a background task.

Proposed change
-            result = detect_duplicate(issue_text)
+            from starlette.concurrency import run_in_threadpool
+            result = await run_in_threadpool(detect_duplicate, issue_text)
             print("Duplicate result:", result)

             if result and result["duplicate"]:
-                github.comment_issue(
-                    payload["issue"]["number"],
-                    ...
-                )
+                await run_in_threadpool(
+                    github.comment_issue,
+                    payload["issue"]["number"],
+                    comment_body,
+                )
🤖 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 `@app/api/webhooks.py` around lines 33 - 49, The async webhook handler is
calling blocking work directly, which can stall the event loop and hurt
concurrency; in the webhook flow around detect_duplicate and
github.comment_issue, move both the duplicate detection and the PyGithub issue
comment call off the event loop using a threadpool or background task. Update
the handler in app/api/webhooks.py so the logic around
detect_duplicate(payload["issue"]["body"]) and github.comment_issue(...) is
awaited through an async-safe offload path, keeping the async request handler
non-blocking.

Comment thread app/config.py
Comment thread app/db/vector.py Outdated
Comment thread app/test.py Outdated
Comment thread README.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
README.md (1)

261-268: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Remove the trailing merge-conflict markers.

The README still ends with unresolved conflict artifacts, which leaves the docs in a conflicted state and should block merge.

🤖 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 `@README.md` around lines 261 - 268, The README still contains unresolved
merge-conflict artifacts at the end, so remove the leftover conflict marker
lines from the document and leave only the intended final content. Check the
trailing section of README.md and clean out the stray symbols so the file is no
longer in a conflicted state.
🤖 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 `@app/config.py`:
- Line 10: Validate the SIMILARITY_THRESHOLD setting in app/config.py before it
is consumed by detect_duplicate(); make sure the value is constrained to the 0–1
range and falls back to a safe default if the environment variable is missing or
invalid. Update the config initialization around SIMILARITY_THRESHOLD so
downstream duplicate checking cannot be broken by 0, negative, or >1 values.

In `@app/ml/clean.py`:
- Around line 20-27: The cleaned issue payload and ingestion code are out of
sync: clean_issue() now returns an "embedding" field, but the ingestion path in
app/db/ingest.py still expects cleaned["vector"]. Update the schema to use one
consistent key across both places, either by changing clean_issue() to return
"vector" or by updating the ingestion logic that consumes clean_issue() to read
"embedding" instead. Keep the fix localized around clean_issue() and the ingest
flow that persists to ChromaDB.

---

Duplicate comments:
In `@README.md`:
- Around line 261-268: The README still contains unresolved merge-conflict
artifacts at the end, so remove the leftover conflict marker lines from the
document and leave only the intended final content. Check the trailing section
of README.md and clean out the stray symbols so the file is no longer in a
conflicted state.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5a1a2a4e-0320-4c85-b005-0536dc701467

📥 Commits

Reviewing files that changed from the base of the PR and between b86ddae and c02652f.

📒 Files selected for processing (12)
  • .env.example
  • .gitignore
  • README.md
  • app/api/webhooks.py
  • app/config.py
  • app/core/github.py
  • app/db/ingest.py
  • app/db/vector.py
  • app/ml/clean.py
  • app/ml/duplicate.py
  • app/ml/embedder.py
  • app/test.py
💤 Files with no reviewable changes (1)
  • .env.example
✅ Files skipped from review due to trivial changes (1)
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (6)
  • app/test.py
  • app/db/vector.py
  • app/ml/embedder.py
  • app/ml/duplicate.py
  • app/db/ingest.py
  • app/core/github.py

Comment thread app/config.py Outdated
Comment thread app/ml/clean.py
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.

2 participants