Skip to content

fix: add current_id filter to find_similar_comments_nomic RPC - #157

Closed
sungdark wants to merge 2 commits into
ubiquity-os-marketplace:developmentfrom
sungdark:pr-155-fix
Closed

sungdark wants to merge 2 commits into
ubiquity-os-marketplace:developmentfrom
sungdark:pr-155-fix

Conversation

@sungdark

@sungdark sungdark commented Apr 1, 2026

Copy link
Copy Markdown

Summary

Fixes a bug identified in code review where the Nomic similarity search was missing the current_id filter, allowing the current comment to appear in its own similarity results.

Changes

SQL Migration (20260331000000_nomic_embedding.sql)

  • Added current_id parameter to find_similar_comments_nomic function
  • Added WHERE id <> current_id filter to exclude the current comment

TypeScript (src/adapters/supabase/helpers/comment.ts)

  • Pass current_id to the find_similar_comments_nomic RPC call

Bug Details

The original implementation in PR #155 called find_similar_comments_nomic without passing current_id, while the equivalent Voyage function (find_similar_comments_annotate) correctly filtered by current_id. This could cause the current comment to appear in its own similarity search results.

References

sungdark and others added 2 commits March 31, 2026 04:40
Implements dual-model embedding architecture:
- Adds Nomic Embed v1.5 model (768d) alongside Voyage-4-large (1024d)
- Nomic provides ~10% higher retrieval accuracy (86.2% vs 75-77%)
- New 'embeddingModel' plugin setting: 'voyage' (default) or 'nomic'
- New NOMIC_API_KEY environment variable (optional)
- Adds nomic_embedding column to documents table with IVFFlat index
- Adds Nomic-specific RPC functions for similarity search
- Issue/review_comment creation: both models store embeddings when NOMIC_API_KEY is set
- Similarity search: uses configured model for query embedding

Ref: ubiquity-os-marketplace#111
Devpool: devpool-directory#5064 (00)
Fixes a bug identified in code review where the Nomic similarity search
was missing the current_id filter, allowing the current comment to
appear in its own similarity results.

Changes:
- SQL: Added current_id parameter to find_similar_comments_nomic function
  and added WHERE id <> current_id filter
- TS: Pass current_id to the RPC call

Refs:
- ubiquity-os-marketplace#111
- devpool-directory/devpool-directory#5064
- Code review: PR ubiquity-os-marketplace#155 comment from coderabbitai
@ubiquity-os-beta

Copy link
Copy Markdown
Contributor

Related issues suggestions

Select one (or more) issue(s) to link:

@github-actions

github-actions Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Unused exports (1)

Filename exports
src/adapters/index.ts serializeEmbeddingForDatabase

Unused types (1)

Filename types
src/adapters/index.ts EmbeddingModel

@coderabbitai

coderabbitai Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This change introduces support for Nomic embeddings as an alternative to Voyage embeddings throughout the system. It adds a new NOMIC_API_KEY environment variable, a embeddingModel configuration option (defaulting to "voyage"), and a Nomic embedding adapter with a 768-dimensional model. The database schema is extended with a nomic_embedding column on documents, along with corresponding indexes and SQL functions for similarity searches. Comment and issue handling logic is updated to generate and persist Nomic embeddings when the API key is configured, while maintaining existing Voyage embedding support.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning Description lacks the required issue link format. Template requires 'Resolves #' but PR provides context instead. Add 'Resolves #111' at the top following the template format, keeping the detailed summary as supplementary context.
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 (1 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately describes the main fix: adding current_id filter to find_similar_comments_nomic RPC to prevent self-matching.

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (2)
src/adapters/index.ts (1)

14-14: Unused type export flagged by pipeline.

EmbeddingModel is exported but never imported elsewhere. Either use it in comment.ts/issues.ts instead of the inline "voyage" | "nomic" type, or remove it.

src/adapters/supabase/helpers/comment.ts (1)

47-50: Consider using the exported EmbeddingModel type from src/adapters/index.ts.

The return type "voyage" | "nomic" is defined inline here but also exported as EmbeddingModel in src/adapters/index.ts. Using the shared type would ensure consistency if more models are added.

♻️ Proposed change
+import { EmbeddingModel } from "../../../adapters/index";
+
-function getEmbeddingModel(context: Context): "voyage" | "nomic" {
+function getEmbeddingModel(context: Context): EmbeddingModel {
   const config = context.config as PluginSettings | undefined;
   return config?.embeddingModel ?? "voyage";
 }

This would also address the unused EmbeddingModel export flagged by pipeline.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0b4d01a4-18a7-44b9-b610-da1a10db0575

📥 Commits

Reviewing files that changed from the base of the PR and between efc5a9d and 3e3c44a.

📒 Files selected for processing (11)
  • README.md
  • src/adapters/index.ts
  • src/adapters/nomic/helpers/embedding.ts
  • src/adapters/nomic/helpers/nomic.ts
  • src/adapters/supabase/helpers/comment.ts
  • src/adapters/supabase/helpers/issues.ts
  • src/cron/reprocess.ts
  • src/types/database.ts
  • src/types/env.ts
  • src/types/plugin-input.ts
  • supabase/migrations/20260331000000_nomic_embedding.sql

Comment thread src/adapters/index.ts
Comment on lines +54 to +56
export function serializeEmbeddingForDatabase(embedding: number[] | null): string | null {
return embedding ? JSON.stringify(embedding) : null;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Duplicate function — already exists in src/utils/database-embedding.ts.

Pipeline reports this as unused. The same function is defined and imported from src/utils/database-embedding.ts (see context snippet 3 and line 5 of comment.ts). Remove this duplicate.

🗑️ Proposed fix
-
-export function serializeEmbeddingForDatabase(embedding: number[] | null): string | null {
-  return embedding ? JSON.stringify(embedding) : null;
-}
📝 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
export function serializeEmbeddingForDatabase(embedding: number[] | null): string | null {
return embedding ? JSON.stringify(embedding) : null;
}
🧰 Tools
🪛 GitHub Actions: Knip

[error] 54-54: KNIP reported unused exports: 'serializeEmbeddingForDatabase' is unused (Unused exports (1)).

Comment on lines +25 to +26
const embeddings = await this.createEmbeddings([text], inputType);
return embeddings[0] ?? [];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Reject malformed embeddings instead of returning them.

Line 26 can return [], and Lines 67-70 only warn on a dimension mismatch. That pushes bad vectors into vector(768) writes/RPCs and fails later. Throw as soon as the response count or dimensions are wrong.

Possible fix
   const embeddings = await this.createEmbeddings([text], inputType);
-  return embeddings[0] ?? [];
+  const [embedding] = embeddings;
+  if (!embedding) {
+    throw new Error("Invalid response from Nomic API: expected one embedding");
+  }
+  return embedding;
@@
-    const dims = data.embeddings[0]?.length;
-    if (dims !== NOMIC_EMBEDDING_DIM) {
-      this.context.logger.warn(`Nomic embedding dimension mismatch. Expected ${NOMIC_EMBEDDING_DIM}, got ${dims}`);
+    const invalidEmbedding = data.embeddings.find((embedding) => embedding.length !== NOMIC_EMBEDDING_DIM);
+    if (invalidEmbedding) {
+      throw new Error(`Invalid response from Nomic API: expected ${NOMIC_EMBEDDING_DIM} dimensions, got ${invalidEmbedding.length}`);
     }

Also applies to: 67-73

Comment on lines +42 to +54
const response = await fetch("https://api.atlas.nomic.ai/v1/embedding/text", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify({
texts,
model: NOMIC_MODEL,
task_type: inputType,
truncation: true,
}),
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Does the JS runtime targeted by this repo provide any default timeout for fetch, or do outbound requests need an explicit AbortController/signal to avoid hanging for too long?

💡 Result:

The JS runtime targeted by this repo (likely Bun, Deno, or Node.js based on common modern JS server-side runtimes with fetch) does provide default timeouts for fetch in some cases, but behavior varies: - Bun: Yes, implements a default ~5-minute timeout (increased from 60s in 2023 via PR #6217). Can be disabled with {timeout: false} (Bun-specific, undocumented in types). Official docs recommend AbortSignal.timeout for explicit timeouts, implying no standard signal default but runtime-level timeout exists. Requests hang until this timeout without explicit signal. - Deno: No default timeout for fetch. Requests can hang indefinitely until TCP/gateway timeout unless explicit AbortController/signal provided. Docs and sources confirm reliance on user-provided AbortSignal for timeouts. - Node.js (undici fetch): Yes, multiple defaults (e.g., connect ~10s, headers ~5min/300s). Times out automatically (e.g., UND_ERR_HEADERS_TIMEOUT); configure via custom Agent/dispatcher or AbortSignal. Without repo link, assuming Bun (most matching evidence), outbound requests have a default 5min timeout but need explicit AbortController/signal (or Bun's {timeout: false} to disable) for custom shorter timeouts to avoid hanging up to 5min.

Citations:


🏁 Script executed:

# Check for package.json and identify runtime target
cd /tmp && find . -maxdepth 2 -name "package.json" -o -name "deno.json" -o -name "tsconfig.json" | head -20

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 72


🏁 Script executed:

# First, find the exact file
fd -t f "embedding.ts" --path "*nomic*"

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 323


🏁 Script executed:

# Check package.json for runtime clues (bun, node, deno indicators)
cat package.json 2>/dev/null | head -50

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 1956


🏁 Script executed:

# Find and read the embedding.ts file
find . -type f -name "embedding.ts" 2>/dev/null | head -5

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 174


🏁 Script executed:

# Check if the file exists at the specified path
cat -n src/adapters/nomic/helpers/embedding.ts 2>/dev/null | sed -n '35,60p'

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 953


🏁 Script executed:

# Search for AbortController or timeout patterns in the codebase
rg -i "abortcontroller|abortSignal|signal.*controller" --type ts --type js

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 72


🏁 Script executed:

# Search for other fetch calls in the codebase
rg "fetch\(" --type ts --type js -A 5 | head -80

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 1512


🏁 Script executed:

# Check if there's any timeout configuration or patterns in Nomic adapter
cat -n src/adapters/nomic/helpers/embedding.ts

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 2872


Add a timeout to the Nomic API request.

This fetch() call has no abort signal. A slow or unresponsive Nomic API can block embedding operations indefinitely, holding up writes and similarity lookups. Node.js provides no short default timeout for fetch—requests can hang for several minutes. Add an explicit AbortController with a bounded timeout and handle the AbortError to surface timeout failures clearly.

Comment on lines +202 to +212
const updateData: Record<string, unknown> = {
doc_type: docType,
markdown: finalMarkdown,
embedding: serializeEmbeddingForDatabase(embedding),
payload: finalPayload,
modified_at: new Date(),
};

if (nomicEmbedding) {
updateData.nomic_embedding = serializeEmbeddingForDatabase(nomicEmbedding);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Clear stale nomic_embedding on update.

Line 210 only writes nomic_embedding when a fresh vector exists. The _nomic RPCs in supabase/migrations/20260331000000_nomic_embedding.sql Lines 83-90 and 105-112 only check nomic_embedding IS NOT NULL, so a private or shortened issue can remain searchable via its old vector. Persist null here when no new Nomic embedding was produced.

Possible fix
 const updateData: Record<string, unknown> = {
   doc_type: docType,
   markdown: finalMarkdown,
   embedding: serializeEmbeddingForDatabase(embedding),
+  nomic_embedding: serializeEmbeddingForDatabase(nomicEmbedding),
   payload: finalPayload,
   modified_at: new Date(),
 };
-
-if (nomicEmbedding) {
-  updateData.nomic_embedding = serializeEmbeddingForDatabase(nomicEmbedding);
-}

Comment on lines +286 to +287
if (model === "nomic" && isNomicAvailable(this.context)) {
const nomicEmbedding = await this.context.adapters.nomic.embedding.createEmbedding(embeddingSource);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

For nomic-embed-text-v1.5, should retrieval queries use task_type: "search_query"while indexed documents usetask_type: "search_document"?

💡 Result:

Yes, for nomic-embed-text-v1.5, retrieval queries should use task_type: "search_query" while indexed documents should use task_type: "search_document".

Citations:


🏁 Script executed:

# First, check the Nomic embedding helper to see the default behavior
head -40 src/adapters/nomic/helpers/embedding.ts | cat -n

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 1583


🏁 Script executed:

# Check lines around 287 and 354 in the issues file
sed -n '280,295p' src/adapters/supabase/helpers/issues.ts | cat -n
sed -n '350,360p' src/adapters/supabase/helpers/issues.ts | cat -n

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 1335


🏁 Script executed:

# Search for all createEmbedding calls to the Nomic adapter
rg "nomic\.embedding\.createEmbedding" --context 3

Repository: ubiquity-os-marketplace/text-vector-embeddings

Length of output: 5137


Pass "search_query" for query-time Nomic embeddings.

The createEmbedding() method defaults to "search_document", but lines 287 and 354 are retrieval queries that require "search_query" for correct embedding semantics. This affects retrieval quality.

Suggested fix
-        const nomicEmbedding = await this.context.adapters.nomic.embedding.createEmbedding(embeddingSource);
+        const nomicEmbedding = await this.context.adapters.nomic.embedding.createEmbedding(embeddingSource, "search_query");

Apply to both locations (lines 287 and 354).

📝 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
if (model === "nomic" && isNomicAvailable(this.context)) {
const nomicEmbedding = await this.context.adapters.nomic.embedding.createEmbedding(embeddingSource);
if (model === "nomic" && isNomicAvailable(this.context)) {
const nomicEmbedding = await this.context.adapters.nomic.embedding.createEmbedding(embeddingSource, "search_query");

sub.similarity
FROM (
SELECT id AS issue_id,
((0.8 * (1 - cosine_distance(query_embedding, nomic_embedding))) + 0.8 * (1 / (1 + l2_distance(query_embedding, nomic_embedding)))) as similarity

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix the blended-score coefficients.

Lines 41 and 64 weight both terms at 0.8, unlike the other RPCs in this file where the weights sum to 1.0. That lets these scores reach 1.6 and makes threshold filtering much looser than intended. The second coefficient looks like it should be 0.2.

Possible fix
-               ((0.8 * (1 - cosine_distance(query_embedding, nomic_embedding))) + 0.8 * (1 / (1 + l2_distance(query_embedding, nomic_embedding)))) as similarity
+               ((0.8 * (1 - cosine_distance(query_embedding, nomic_embedding))) + 0.2 * (1 / (1 + l2_distance(query_embedding, nomic_embedding)))) as similarity

Apply the same change to both find_similar_issues_nomic and find_similar_comments_nomic.

Also applies to: 64-64

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