Skip to content

feat: add matryoshka embedding truncation#6606

Draft
Bbbtt04 wants to merge 1 commit into
FlowiseAI:mainfrom
Bbbtt04:codex/matryoshka-embeddings
Draft

feat: add matryoshka embedding truncation#6606
Bbbtt04 wants to merge 1 commit into
FlowiseAI:mainfrom
Bbbtt04:codex/matryoshka-embeddings

Conversation

@Bbbtt04

@Bbbtt04 Bbbtt04 commented Jul 9, 2026

Copy link
Copy Markdown

Summary

  • Add an optional Document Store embedding setting to keep only the first N embedding dimensions for Matryoshka-compatible models.
  • Apply truncation consistently for document indexing and retrieval query embeddings.
  • Keep the provider init inputs clean while recording the truncation setting in upsert history.

Closes #4361

Tests

  • pnpm --filter flowise-components exec jest src/matryoshkaEmbeddings.test.ts --runInBand
  • pnpm --filter flowise-components exec tsc --noEmit --pretty false
  • pnpm --filter flowise-components exec eslint src/matryoshkaEmbeddings.ts src/matryoshkaEmbeddings.test.ts nodes/vectorstores/DocumentStoreVS/DocStoreVector.ts --ext ts --max-warnings 0
  • pnpm exec eslint packages/server/src/services/documentstore/index.ts packages/ui/src/views/docstore/VectorStoreConfigure.jsx --ext ts,jsx --max-warnings 0
  • pnpm --filter flowise-components build
  • pnpm --filter './packages/server' exec tsc --noEmit --pretty false
  • pnpm --filter flowise-ui build

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

Code Review

This pull request introduces Matryoshka embedding truncation support, allowing users to optionally truncate document and query embeddings to a configured dimension. It adds a utility module matryoshkaEmbeddings.ts along with unit tests, integrates this truncation into the document store services, and updates the UI to support configuring the truncation dimensions. The review feedback highlights a potential runtime crash when using Object.create on embedding instances that utilize native JavaScript private fields, suggesting a monkey-patching approach instead. Additionally, it recommends using loose equality (== null) for nullish checks in accordance with standard idioms.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +22 to +34
const wrappedEmbeddings = Object.create(embeddings) as T

wrappedEmbeddings.embedDocuments = async (documents: string[]): Promise<number[][]> => {
const vectors = await embeddings.embedDocuments(documents)
return vectors.map((vector) => truncateVector(vector, dimension))
}

wrappedEmbeddings.embedQuery = async (document: string): Promise<number[]> => {
const vector = await embeddings.embedQuery(document)
return truncateVector(vector, dimension)
}

return wrappedEmbeddings

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.

high

Using Object.create(embeddings) to wrap the embeddings instance can cause runtime crashes if the underlying class uses native JavaScript private fields (e.g., #apiKey). Any non-overridden method called on the prototype-derived wrappedEmbeddings object that accesses these private fields will throw a TypeError: Cannot read private member from an object whose class did not declare it.

Since the embedding instance is created fresh for each operation and is not shared globally, directly monkey-patching the methods on the original embeddings instance is a much safer and robust approach that preserves the this context and private field access.

    const originalEmbedDocuments = embeddings.embedDocuments.bind(embeddings)
    const originalEmbedQuery = embeddings.embedQuery.bind(embeddings)

    embeddings.embedDocuments = async (documents: string[]): Promise<number[][]> => {
        const vectors = await originalEmbedDocuments(documents)
        return vectors.map((vector) => truncateVector(vector, dimension))
    }

    embeddings.embedQuery = async (document: string): Promise<number[]> => {
        const vector = await originalEmbedQuery(document)
        return truncateVector(vector, dimension)
    }

    return embeddings

export const MATRYOSHKA_TRUNCATE_DIMENSIONS = 'matryoshkaTruncateDimensions'

const parseTruncateDimension = (value: unknown): number | undefined => {
if (value === undefined || value === null || value === '') return undefined

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.

medium

According to the general rules, loose equality (== null) should be used as a standard idiom for a 'nullish' check that covers both null and undefined.

Suggested change
if (value === undefined || value === null || value === '') return undefined
if (value == null || value === '') return undefined
References
  1. In JavaScript/TypeScript, use loose equality (== null) as a standard idiom for a 'nullish' check that covers both 'null' and 'undefined'.

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.

[FEATURE] Allow using Matryoshka Embeddings

1 participant