feat: separate internal schema dimensions from embedding API request dimensions#377
feat: separate internal schema dimensions from embedding API request dimensions#377jszhang98 wants to merge 4 commits intoCortexReach:masterfrom
Conversation
AliceLJY
left a comment
There was a problem hiding this comment.
LGTM — clean separation of concerns.
The decoupling of dimensions (internal schema) from requestDimensions (API payload) is the right fix. Solves the problem for non-matryoshka models that reject dimensions in requests.
Tests cover all three cases (no requestDimensions → not sent, requestDimensions set → forwarded, omitDimensions trumps all). Schema updated.
@rwmjhb ready for merge.
JiwaniZakir
left a comment
There was a problem hiding this comment.
The assignment change in embedder.ts at line 434 (this._requestDimensions = config.requestDimensions) is a silent breaking change for existing users. Anyone who previously set only dimensions and relied on it being forwarded to the OpenAI-compatible API (e.g., for text-embedding-3-small with a reduced dimension like 256) will now silently receive full-size embeddings from the provider. If they already have stored vectors at the reduced dimension, this will cause shape mismatches at query time with no warning surfaced to the user.
There's also no test covering the scenario where requestDimensions is omitted but dimensions is set — the test suite now only validates the happy path (requestDimensions: 4 present) and the omitDimensions override. A test asserting that omitting requestDimensions results in no dimensions field in the API request (distinct from the omitDimensions path) would make the contract explicit and catch regressions.
Finally, parsePluginConfig in index.ts gives dimensions a legacy top-level fallback (embedding.dimensions ?? cfg.dimensions), but requestDimensions has no such fallback — that asymmetry is fine given the intent, but it's worth a comment explicitly noting it's not an oversight.
|
This change is valuable. Separating internal schema dimensions from request payload dimensions is the right direction, and it should avoid provider-side 400s for models/endpoints that reject I found one blocking issue before merge:
Relevant spots:
Suggested fix:
Non-blocking note:
With the test suite aligned to the new semantics, this looks like a good change to land. |
|
Update: pushed a follow-up test-only commit ( Validated locally:
For CI context:
|
|
Thanks for the review. The blocking issue is fixed in follow-up commit
For the non-blocking suggestion: agreed. |
|
Thanks for the review — addressed.
I also re-checked locally:
Please take another look when convenient. |
|
So the new config contract is incomplete right now. Either:
|
jszhang98
left a comment
There was a problem hiding this comment.
Per your feedback, internal validation now prioritizes requestDimensions if present, ensuring local checks match the API output for variable-dimension models. All tests pass except for known unrelated failures in reflection-bypass-hook.
Let me know if any further changes are needed!
AliceLJY
left a comment
There was a problem hiding this comment.
LGTM — changes are clean, on-topic, and well-tested. Approving.
Review: separate internal schema dimensions from embedding API request dimensionsVerdict: request-changes | Confidence: 0.90 | Value: 38% The decoupling intent makes sense — separating internal schema sizing from the API request hint is cleaner than Must Fix1. Silent breaking change for reduced-dimension users (HIGH)
This breaks all users relying on reduced-dimension embeddings without warning. @JiwaniZakir flagged the same scenario in their review. Suggestion: when 2. Store schema uses The advertised decoupling doesn't work unless both fields are equal, which defeats the purpose. The store sizing path needs to be aware of 3. Rebase required — build is red (stale base)
Nice to Have
Auto-reviewed by auto-pr-review-orchestrator | 6 rounds | Claude + Codex adversarial |
|
The separation makes sense, but worth confirming the fallback behavior when neither |
|
Thanks for the thoughtful feedback. I agree we should make the fallback behavior explicit and avoid surprises. I’m going to keep the current functional behavior, but make it clearer and test-covered with a minimal follow-up: Add debug logging when dimensions is set but requestDimensions is not, to make it explicit that dimensions is used for internal schema/validation only and is not forwarded to the embedding API. |
|
The separation makes sense, but worth clarifying the migration path for existing users who currently rely on |
|
Thanks, this is a great callout. You’re right about migration risk: users who previously relied on embedding.dimensions being forwarded could silently stop sending a request-side dimension unless requestDimensions is explicitly set. I’ll add a migration note plus a config-time/deprecation warning to make that transition explicit. On validation timing: we still fail fast on embedding length mismatch before persistence (not only at LanceDB insert time). The effective validation dimension follows the current precedence rule (requestDimensions when set, otherwise dimensions), and I’ll document that clearly in the same update. |
|
The separation of |
|
Thanks, this is a great point. |
|
The stray |
|
Agreed on priority: a syntax issue is blocking, so we’ll patch that first before further review. Also agreed on migration safety: we’ll add a runtime warning during embedder/provider initialization when dimensions is set but requestDimensions is not, so users get an immediate signal instead of relying only on migration notes. If this line of work is continued in #482, we’ll ensure that PR includes both: the syntax fix, and |
|
The separation looks correct in principle, but there's a potential issue at the validation boundary: if |
|
Thanks, great boundary callout. You’re right to focus on the validation/source-of-truth path. That said, there is still a real boundary risk if schema sizing and request-time sizing are derived from different fields. I’ll align the schema dimension source with the same effective dimension rule and add explicit tests for: dimensions only, |
|
One edge case worth flagging: if |
|
Re-checking after the follow-up, I still see one blocking issue before merge. On the current PR head (
So a config like The April 3 follow-up comment said schema sizing would be aligned to the same effective-dimension rule, but I don’t see that change in the branch yet. Once store sizing and embedder validation use the same source of truth for the effective dimension, or the PR explicitly rejects mismatched configs, this looks ready from my side. Non-blocking: the migration/deprecation warning for |
AliceLJY
left a comment
There was a problem hiding this comment.
Revisiting after the latest review comment — there's a valid blocking issue.
Problem: The effective dimension source-of-truth is split:
Embeddervalidates againstrequestDimensions ?? dimensions- Store initialization sizes the LanceDB table via
getVectorDimensions(model, dimensions)— ignoringrequestDimensions
This means a config like text-embedding-3-large + requestDimensions: 1024 will pass embedder validation but hit a dimension mismatch at the storage layer.
What's needed:
Store sizing must use the same effective dimension as the embedder: requestDimensions ?? dimensions ?? modelDefault. Once both paths converge on the same source, this is ready to merge.
The migration warning for dimensions-only configs can be a follow-up.
|
Superseded by #572, which rebases the fix onto current \ and closes the remaining request-dimension/schema-sizing mismatch called out in review. |
PR Title
feat: separate internal schema dimensions from embedding API request dimensions
Summary
This PR decouples two previously conflated dimension semantics in the embedding pipeline:
After this change:
embedding.dimensionsis treated as internal schema/validation dimension.embedding.requestDimensionsis optional and only used for API request payload fields.requestDimensionsis not configured, no dimensions field is sent to embedding APIs by default.omitDimensions=truestill has highest priority and suppresses dimensions fields even whenrequestDimensionsis set.Motivation
Some providers/models (for example non-matryoshka-compatible models) reject
dimensions/output_dimensionin request payloads.Previously,
embedding.dimensionswas reused for both storage and API request parameters, which could cause provider-side 400 errors during startup/runtime.This PR keeps storage behavior stable while preventing accidental request-parameter injection.
What Changed
requestDimensions.dimensionstorequestDimensions.requestDimensionsexplicitly.embedding.requestDimensions.Behavior Matrix
dimensionsonly:requestDimensionsset:dimensions/output_dimension).requestDimensions+omitDimensions=true:Backward Compatibility
embedding.dimensionsto API payload should migrate toembedding.requestDimensions.Files Updated
Testing
embedding.requestDimensions.jitipackage dependency, but modified regression logic and assertions are in place.