Skip to content

feat(ui): differentiate issues and PRs in similar threads#75

Merged
Kavirubc merged 2 commits intosimiligh:mainfrom
mahsumaktas:feat/issue-type-badge
Feb 19, 2026
Merged

feat(ui): differentiate issues and PRs in similar threads#75
Kavirubc merged 2 commits intosimiligh:mainfrom
mahsumaktas:feat/issue-type-badge

Conversation

@mahsumaktas
Copy link
Copy Markdown
Contributor

@mahsumaktas mahsumaktas commented Feb 18, 2026

Summary

Adds visual type differentiation in the Similar Threads table so users can instantly tell whether a match is an issue or a pull request.

Closes #49

Changes

internal/core/pipeline/pipeline.go

  • Added Type string field to SimilarIssue struct ("issue" or "pr")

internal/steps/similarity.go

  • Extracts type from Qdrant payload during similarity search
  • normalizeSimilarThreadType() handles variants (pr, pull_request, pull request) and defaults to "issue"

internal/steps/response_builder.go

  • Updated table header: | Similarity | Type | Thread | Status |
  • Added similarThreadTypeIcon() — returns 📝 for issues, 🔀 for PRs

Before / After

Before:

| Similarity | Thread | Status |
| 95% | #123 Fix login bug | Open |

After:

| Similarity | Type | Thread | Status |
| 95% | 📝 | #123 Fix login bug | Open |
| 82% | 🔀 | #124 Refactor auth | Closed |

Tests

  • TestNormalizeSimilarThreadType — 7 cases (empty, issue, PR, pull_request, unknown)
  • TestResponseBuilder_buildSimilarSection_TypeIcons — verifies icons for issue/PR/missing type
  • Updated existing TestResponseBuilder_buildTriageSummary for new table format
  • All tests pass: go test ./...

Summary by CodeRabbit

Release Notes

  • New Features
    • Similar threads section now displays the type of each item (issue or pull request) with visual icons (🔀 for PRs, 📝 for issues), making it easier to distinguish between item types at a glance.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 18, 2026

📝 Walkthrough

Walkthrough

The pull request adds visual differentiation between Issues and Pull Requests in similarity search results by introducing a Type field to the SimilarIssue struct, extracting type information from Qdrant payloads, normalizing thread type identifiers, and rendering type icons in the response markdown table.

Changes

Cohort / File(s) Summary
Data Model
internal/core/pipeline/pipeline.go
Added Type string field to SimilarIssue struct to classify each similar item as "issue" or "pr".
Similarity Processing
internal/steps/similarity.go, internal/steps/similarity_test.go
Introduced normalizeSimilarThreadType helper to map thread type identifiers ("pr", "pull_request", "pull request") to canonical forms, then extract and normalize type from Qdrant payload and assign to SimilarIssue.Type. Added comprehensive unit tests covering edge cases and type mappings.
Response Rendering
internal/steps/response_builder.go, internal/steps/response_builder_test.go
Updated Similar Threads markdown table to include Type column with icons via new similarThreadTypeIcon helper (📝 for issues, 🔀 for PRs). Tests verify icon rendering for various type values and updated table structure.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A thread-type helper hops along,
Extracting types from payloads strong!
📝 and 🔀 now brightly gleam,
Simili-Bot's clarity dream! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

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.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(ui): differentiate issues and PRs in similar threads' accurately summarizes the main change—adding visual differentiation for issues vs PRs in the Similar Threads table.
Linked Issues check ✅ Passed All objectives from issue #49 are met: Type field added to SimilarIssue struct, thread type extracted from Qdrant payload with normalization, and icon display (📝 for issues, 🔀 for PRs) implemented in response builder with comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing visual differentiation for issues vs PRs: pipeline model updates, similarity step extraction, response builder icon display, and related test additions. No extraneous modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

Signed-off-by: Mahsum Aktas <mahsum@mahsumaktas.com>
Copy link
Copy Markdown
Contributor

@Kavirubc Kavirubc left a comment

Choose a reason for hiding this comment

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

Clean, well-scoped implementation. The three-layer change (struct → similarity step → response builder) is exactly right, and the defensive defaulting in normalizeSimilarThreadType() means no regressions for existing Qdrant payloads that lack a type field.

Two minor nits, neither blocking:

  • The "pull_request" and "pull request" cases in similarThreadTypeIcon() are unreachable in practice since normalizeSimilarThreadType() always normalizes to "pr" before the icon function sees the value. Safe to simplify that switch to just case "pr": if you want, or leave it as a defensive belt-and-suspenders — either is fine.
  • If more thread types (e.g. "discussion") are added later, both switch blocks will need updating in sync. Worth a comment linking them or extracting a shared type constant at that point.

All CI green, tests cover the happy path, PR type, and missing type. Approving.

@Kavirubc Kavirubc added the e2e label Feb 19, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
internal/steps/similarity_test.go (1)

5-27: Good coverage — consider adding an uppercase PR variant.

All documented variants and the default are exercised. One minor gap: while "ISSUE" verifies case-folding for the default branch, there is no equivalent test (e.g. "PR" or "PULL_REQUEST") verifying that the "pr" branch is also case-folded. Adding one case closes the symmetry.

💡 Suggested additional case
 {name: "pr stays pr", input: "pr", expected: "pr"},
+{name: "uppercase pr", input: "PR", expected: "pr"},
 {name: "pull request alias", input: "pull_request", expected: "pr"},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/steps/similarity_test.go` around lines 5 - 27, The test suite for
normalizeSimilarThreadType is missing a case to verify case-folding for PR
variants; add an extra test case in TestNormalizeSimilarThreadType (the tests
slice) such as name: "uppercase pr", input: "PR" (or "PULL_REQUEST"), expected:
"pr" so the normalizeSimilarThreadType function's PR branch is validated for
uppercase inputs.
internal/steps/response_builder.go (1)

264-271: similarThreadTypeIcon re-encodes PR-variant matching that normalizeSimilarThreadType already handles.

By the time SimilarIssue.Type arrives here it is already canonical ("pr" or "issue"); the "pull_request" / "pull request" branches are dead code in the production call path. This duplicates the variant list from similarity.go:39-41, so adding a new alias later (e.g. "merge_request") requires updating two places.

Consider simplifying to operate only on canonical values, which also explicitly documents the expected contract:

♻️ Proposed simplification
 func similarThreadTypeIcon(threadType string) string {
-	switch strings.ToLower(strings.TrimSpace(threadType)) {
-	case "pr", "pull_request", "pull request":
+	switch threadType {
+	case "pr":
 		return "🔀"
 	default:
 		return "📝"
 	}
 }

If defensive handling of raw payload values is intentional, at minimum extract the canonical PR-variant set into a shared constant or helper so both functions stay in sync.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/steps/response_builder.go` around lines 264 - 271, The
similarThreadTypeIcon function duplicates PR-variant matching already performed
by normalizeSimilarThreadType and receives canonical values via
SimilarIssue.Type, so remove the dead branches and simplify
similarThreadTypeIcon to switch only on canonical values (e.g., "pr" and default
"issue") or, if you want defensive handling, pull the PR alias set into a shared
constant/helper used by both similarThreadTypeIcon and
normalizeSimilarThreadType (update similarity.go to expose the alias set or
helper). Update references to similarThreadTypeIcon and
normalizeSimilarThreadType to use the shared helper where applicable so adding
new aliases requires changing only one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/steps/response_builder.go`:
- Around line 264-271: The similarThreadTypeIcon function duplicates PR-variant
matching already performed by normalizeSimilarThreadType and receives canonical
values via SimilarIssue.Type, so remove the dead branches and simplify
similarThreadTypeIcon to switch only on canonical values (e.g., "pr" and default
"issue") or, if you want defensive handling, pull the PR alias set into a shared
constant/helper used by both similarThreadTypeIcon and
normalizeSimilarThreadType (update similarity.go to expose the alias set or
helper). Update references to similarThreadTypeIcon and
normalizeSimilarThreadType to use the shared helper where applicable so adding
new aliases requires changing only one place.

In `@internal/steps/similarity_test.go`:
- Around line 5-27: The test suite for normalizeSimilarThreadType is missing a
case to verify case-folding for PR variants; add an extra test case in
TestNormalizeSimilarThreadType (the tests slice) such as name: "uppercase pr",
input: "PR" (or "PULL_REQUEST"), expected: "pr" so the
normalizeSimilarThreadType function's PR branch is validated for uppercase
inputs.

@gh-simili-bot
Copy link
Copy Markdown
Contributor

🧪 E2E Test

Bot responded: yes

Test repo → gh-simili-bot/simili-e2e-22168890067
Run → logs

Auto-generated by E2E pipeline

@Kavirubc Kavirubc merged commit 78f2e68 into similigh:main Feb 19, 2026
6 checks passed
Sachindu-Nethmin pushed a commit to Sachindu-Nethmin/simili-bot that referenced this pull request Feb 19, 2026
… (similigh#75)

Signed-off-by: Mahsum Aktas <mahsum@mahsumaktas.com>
Co-authored-by: Kaviru Hapuarachchi <41495525+Kavirubc@users.noreply.github.com>
Signed-off-by: Sachindu-Nethmin <sachindunethminweerasinghe@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement] Visually differentiate Issues vs PRs in Similarity Search results

3 participants