Skip to content

feat(embedding): update to Google Generative AI model gemini-embedding-001 and refactor embedding logic - #32

Merged
hoangsonww merged 1 commit into
masterfrom
feat/enhance-embedding-model
Feb 28, 2026
Merged

feat(embedding): update to Google Generative AI model gemini-embedding-001 and refactor embedding logic#32
hoangsonww merged 1 commit into
masterfrom
feat/enhance-embedding-model

Conversation

@hoangsonww

Copy link
Copy Markdown
Owner

This pull request migrates the application's embedding pipeline from the deprecated Google text-embedding-004 model to the new Gemini gemini-embedding-001 model. It introduces a centralized embeddingService for generating, normalizing, and validating embeddings across all vector database integrations (Pinecone, FAISS, Weaviate). The update ensures consistent use of 768-dimensional normalized vectors, simplifies embedding code, and adds robust error handling and test coverage for embedding generation.

Embedding Model Migration

  • All documentation, scripts, and code references to the embedding model have been updated from text-embedding-004 to gemini-embedding-001, reflecting the new default for generating product embeddings. [1] [2] [3] [4]

Centralized Embedding Service

  • Added backend/services/embeddingService.js to encapsulate Gemini embedding logic, including model initialization, request building, vector normalization, and error handling for embedding size mismatches.
  • Refactored all scripts and services (pineconeSync.js, syncPinecone.js, build-faiss-index.js, search-faiss-index.js, weaviate-upsert.js) to use the new embeddingService for generating embeddings, removing direct usage of the Google Generative AI SDK. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]

Testing and Validation

  • Introduced unit tests for embeddingService to verify request construction, embedding normalization, and error handling for incorrect embedding sizes.

Documentation Updates

  • Updated architecture and agent documentation to reflect the new embedding model and its integration details. [1] [2] [3] [4]

Codebase Simplification

  • Removed redundant model initialization and embedding logic from all scripts/services, ensuring all embedding requests are routed through the centralized service for consistency and maintainability. [1] [2] [3] [4] [5]

Let me know if you have any questions about the new embedding workflow or how to use the embeddingService!

@hoangsonww hoangsonww added this to the v1.x.x - Stable Release milestone Feb 28, 2026
@hoangsonww hoangsonww self-assigned this Feb 28, 2026
Copilot AI review requested due to automatic review settings February 28, 2026 03:36
@hoangsonww hoangsonww added bug Something isn't working documentation Improvements or additions to documentation duplicate This issue or pull request already exists enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers dependencies Pull requests that update a dependency file labels Feb 28, 2026
@vercel

vercel Bot commented Feb 28, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
mern-stack-ecommerce-app Ignored Ignored Feb 28, 2026 3:36am

@netlify

netlify Bot commented Feb 28, 2026

Copy link
Copy Markdown

Deploy Preview for mern-stack-ecommerce-website ready!

Name Link
🔨 Latest commit f606371
🔍 Latest deploy log https://app.netlify.com/projects/mern-stack-ecommerce-website/deploys/69a262b099d5da000832f319
😎 Deploy Preview https://deploy-preview-32--mern-stack-ecommerce-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 61
Accessibility: 88
Best Practices: 100
SEO: 100
PWA: 80
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@hoangsonww
hoangsonww merged commit 0d459aa into master Feb 28, 2026
7 of 8 checks passed
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly upgrades the application's embedding infrastructure by transitioning to Google's gemini-embedding-001 model. It establishes a unified embeddingService to streamline embedding generation, ensuring consistency, improving maintainability, and enhancing error handling across all vector database integrations. This change centralizes the core logic for creating product embeddings, making the system more robust and easier to manage.

Highlights

  • Embedding Model Migration: The application's embedding pipeline has been migrated from the deprecated Google text-embedding-004 model to the new Gemini gemini-embedding-001 model.
  • Centralized Embedding Service: A new backend/services/embeddingService.js file was introduced to encapsulate all Gemini embedding logic, including model initialization, request building, vector normalization, and error handling.
  • Code Refactoring: All existing scripts and services that generate embeddings (e.g., pineconeSync.js, build-faiss-index.js, weaviate-upsert.js) have been refactored to use the new embeddingService, removing direct usage of the Google Generative AI SDK.
  • Testing and Validation: Unit tests were added for the embeddingService to verify request construction, embedding normalization, and proper error handling for incorrect embedding sizes.
  • Documentation Updates: Relevant documentation files (AGENTS.md, ARCHITECTURE.md, README.md) have been updated to reflect the new gemini-embedding-001 model and its integration.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • AGENTS.md
    • Updated the LLM Integration section to reference gemini-embedding-001.
    • Updated the Pinecone Setup section to reference gemini-embedding-001 for 768-dimensional vectors.
  • ARCHITECTURE.md
    • Modified the flowchart to show gemini-embedding-001 as the Google Generative AI model.
  • README.md
    • Updated the environment variable description to mention gemini-embedding-001.
  • backend/tests/embeddingService.spec.js
    • Added a new test file for embeddingService.
    • Included tests for buildEmbedRequest to verify request structure.
    • Added tests for embedText to confirm vector normalization.
    • Included tests for error handling when an incorrect embedding size is returned.
  • backend/scripts/build-faiss-index.js
    • Removed direct GoogleGenerativeAI import.
    • Imported EMBEDDING_DIMENSION, EMBEDDING_TASK_TYPES, and embedText from embeddingService.
    • Removed explicit embedModel initialization.
    • Updated embedding dimension determination to use EMBEDDING_DIMENSION.
    • Replaced direct embedModel.embedContent calls with embedText from the new service.
    • Adjusted comment numbering for steps.
  • backend/scripts/search-faiss-index.js
    • Removed direct GoogleGenerativeAI import.
    • Imported EMBEDDING_TASK_TYPES and embedText from embeddingService.
    • Removed explicit genAI and model initialization.
    • Replaced direct model.embedContent calls with embedText from the new service.
  • backend/scripts/weaviate-upsert.js
    • Removed direct GoogleGenerativeAI import.
    • Imported embedText and EMBEDDING_TASK_TYPES from embeddingService.
    • Removed explicit genAI and embedModel initialization.
    • Replaced direct embedModel.embedContent calls with embedText from the new service.
  • backend/services/embeddingService.js
    • Added a new file to centralize embedding logic.
    • Defined EMBEDDING_MODEL as gemini-embedding-001 and EMBEDDING_DIMENSION as 768.
    • Defined EMBEDDING_TASK_TYPES for retrieval document and query.
    • Implemented getEmbeddingModel for lazy initialization of the Gemini model.
    • Included normalizeVector function for L2 normalization.
    • Implemented buildEmbedRequest to construct requests for the embedding model.
    • Implemented embedText to handle embedding generation, normalization, and dimension validation.
    • Exported constants and functions for external use.
  • backend/services/pineconeSync.js
    • Removed direct GoogleGenerativeAI import.
    • Imported embedText and EMBEDDING_TASK_TYPES from embeddingService.
    • Removed getEmbedModel function.
    • Replaced direct getEmbedModel().embedContent calls with embedText from the new service.
  • backend/sync/syncPinecone.js
    • Removed direct GoogleGenerativeAI import.
    • Imported embedText and EMBEDDING_TASK_TYPES from embeddingService.
    • Removed explicit genAI and embedModel initialization.
    • Replaced direct embedModel.embedContent calls with embedText from the new service.
Activity
  • The pull request introduces a significant refactoring of the embedding pipeline.
  • New files were added for the centralized embedding service and its unit tests.
  • Multiple existing files were modified to adopt the new service, removing redundant code.
  • Documentation was updated to reflect the changes in the embedding model.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request is a solid refactoring that successfully migrates to the new gemini-embedding-001 model and centralizes embedding logic into a new embeddingService. This greatly improves code structure and maintainability. The changes are applied consistently, and the new service is well-tested. I have a couple of suggestions to further improve maintainability and test isolation.

Comment on lines +19 to +25
beforeAll(() => {
process.env.GOOGLE_AI_API_KEY = 'test-key';
});

beforeEach(() => {
mockEmbedContent.mockReset();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Modifying process.env within tests can cause side effects that interfere with other test suites running in the same process. To ensure test isolation, it's best practice to restore the original environment variable's value after the tests in this suite have completed. You can achieve this by storing the original value before the suite runs and restoring it using an afterAll block.

  const originalApiKey = process.env.GOOGLE_AI_API_KEY;

  beforeAll(() => {
    process.env.GOOGLE_AI_API_KEY = 'test-key';
  });

  afterAll(() => {
    process.env.GOOGLE_AI_API_KEY = originalApiKey;
  });

  beforeEach(() => {
    mockEmbedContent.mockReset();
  });

@@ -0,0 +1,79 @@
require('dotenv').config();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Calling require('dotenv').config() inside a service module can introduce side effects and make configuration management less predictable, as behavior can depend on the order in which modules are imported. It's a common best practice to handle environment configuration at the application's entry point (e.g., in index.js or a dedicated config.js file) to ensure variables are loaded once and consistently across the entire application.

Copilot AI 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.

Pull request overview

This PR migrates the backend embedding pipeline from the deprecated Google model to Gemini (models/gemini-embedding-001) by introducing a centralized embeddingService and refactoring existing Pinecone/FAISS/Weaviate sync scripts/services to use it for consistent 768-dim normalized vectors.

Changes:

  • Added backend/services/embeddingService.js to centralize embedding request construction, dimension enforcement (768), and normalization.
  • Refactored Pinecone sync/service code and FAISS/Weaviate scripts to use embedText(...) with retrieval task types.
  • Added Jest unit tests for embeddingService and updated docs to reflect the new embedding model.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
backend/services/embeddingService.js New shared service for Gemini embeddings (request building, normalization, validation).
backend/tests/embeddingService.spec.js Unit tests covering request shape, normalization, and dimension mismatch errors.
backend/sync/syncPinecone.js Uses embeddingService for embeddings during bulk Pinecone sync.
backend/services/pineconeSync.js Uses embeddingService for per-product Pinecone sync hooks/services.
backend/scripts/build-faiss-index.js Uses embeddingService to generate vectors and sets FAISS index dimension to 768.
backend/scripts/search-faiss-index.js Uses embeddingService to embed queries before FAISS search.
backend/scripts/weaviate-upsert.js Uses embeddingService for embeddings during Weaviate upsert.
README.md Updates docs to reference gemini-embedding-001.
ARCHITECTURE.md Updates architecture diagram text to gemini-embedding-001.
AGENTS.md Updates agent documentation references to gemini-embedding-001.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +55 to +57
const trimmedText = text?.trim();
if (!trimmedText) return null;

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

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

embedText returns null for blank/whitespace input. Since most callers expect an array of 768 floats, this can lead to downstream runtime errors if a whitespace string slips through. Consider throwing a descriptive error for empty input (or returning a consistent empty array) and updating callers accordingly so the contract is unambiguous.

Suggested change
const trimmedText = text?.trim();
if (!trimmedText) return null;
if (typeof text !== 'string') {
throw new TypeError('embedText: `text` must be a non-empty string.');
}
const trimmedText = text.trim();
if (!trimmedText) {
// Return a consistent zero vector when input is blank/whitespace
return new Array(EMBEDDING_DIMENSION).fill(0);
}

Copilot uses AI. Check for mistakes.
Comment on lines 35 to +38
// 2) Embed the query text
const genAI = new GoogleGenerativeAI(GOOGLE_AI_API_KEY);
const model = genAI.getGenerativeModel({ model: 'models/text-embedding-004' });
const embedding = (await model.embedContent(query)).embedding.values;
const embedding = await embedText(query, {
taskType: EMBEDDING_TASK_TYPES.RETRIEVAL_QUERY,
});

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

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

embedText(query) can return null when the CLI argument is only whitespace (because embedText trims internally). In that case index.search(embedding, k) will throw. Consider validating query.trim() before calling embedText, or handle a null return with a clear error/exit path.

Copilot uses AI. Check for mistakes.
@hoangsonww hoangsonww moved this from Done to In progress in Fusion Electronics MERN Project Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation duplicate This issue or pull request already exists enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

2 participants