Skip to content

feat(embedding): add Voyage dense embedding support#635

Merged
qin-ctx merged 4 commits intovolcengine:mainfrom
kfiramar:feat/voyage-text-embeddings-clean
Mar 16, 2026
Merged

feat(embedding): add Voyage dense embedding support#635
qin-ctx merged 4 commits intovolcengine:mainfrom
kfiramar:feat/voyage-text-embeddings-clean

Conversation

@kfiramar
Copy link
Copy Markdown
Contributor

Summary

  • add a dedicated VoyageDenseEmbedder for Voyage's OpenAI-compatible embeddings API
  • register voyage as a first-class dense embedding provider in config
  • use Voyage model defaults when the embedding schema dimension is omitted
  • document the supported Voyage configuration and add focused unit coverage

Why this version is intentionally narrow

This PR adds Voyage dense text embeddings in a way that matches OpenViking's current embedding architecture.

Today OpenViking:

  • configures a single dense embedder for both indexing and query-time retrieval
  • stores and validates dense vectors as float vectors with a fixed schema dimension

Because of that, this PR intentionally does not expose Voyage-specific features that do not fit the current architecture yet:

  • no output_dtype config field
  • no query/document mode in config

Instead, the PR keeps the public surface to the existing generic fields:

  • provider
  • api_key
  • api_base
  • model
  • dimension

For Voyage, dimension is mapped internally to Voyage's output_dimension request field.

Review feedback addressed

This revision directly addresses the review concerns from #614:

  1. output_dtype is not added to EmbeddingModelConfig

    • OpenViking currently expects dense float vectors across storage and retrieval.
    • Exposing Voyage quantized output types now would add provider-specific config surface without a matching end-to-end runtime path.
  2. query/document mode is not documented as a supported config knob

    • OpenViking currently uses one dense embedder configuration for both indexing and querying.
    • Documenting input_type: document/query at this stage would imply asymmetric retrieval support that the current config model does not provide yet.
  3. Voyage support still remains first-class

    • the provider is explicit in config and validation
    • the implementation is isolated in a dedicated embedder instead of being hidden inside the OpenAI path

Implementation details

  • openviking/models/embedder/voyage_embedders.py
    • adds VoyageDenseEmbedder
    • validates allowed output dimensions for Voyage models that support dimension control
    • uses Voyage model defaults when no dimension is specified
  • openviking_cli/utils/config/embedding_config.py
    • validates provider: \"voyage\"
    • returns Voyage model default dimensions through get_effective_dimension() when schema dimension is omitted
    • wires the new provider into the dense embedder factory
  • docs/en/guides/01-configuration.md
    • adds a Voyage config example
    • documents the current architectural limits clearly
  • tests
    • add unit coverage for config validation, dimension defaults, request shaping, and error handling

Verification

  • .venv/bin/python -m pytest tests/unit/test_voyage_embedder.py tests/unit/test_embedding_config_voyage.py --noconftest -o addopts='' -q
  • .venv/bin/python -m pytest tests/misc/test_config_validation.py -o addopts='' -q
  • .venv/bin/ruff check openviking/models/embedder/voyage_embedders.py openviking_cli/utils/config/embedding_config.py tests/unit/test_embedding_config_voyage.py tests/unit/test_voyage_embedder.py

Add first-class Voyage dense embedding support with a dedicated embedder,
provider validation, model-aware default dimensions, and focused tests.

Keep the configuration surface intentionally narrow:
- use the existing dimension field and map it to Voyage's
  output_dimension request field
- do not expose Voyage-only output_dtype
- do not expose query/document mode until OpenViking has separate
  index/query embedder configuration

This keeps the PR aligned with the current OpenViking architecture,
which stores and retrieves dense float vectors through a single dense
embedder configuration.

Verification:
- .venv/bin/python -m pytest tests/unit/test_voyage_embedder.py tests/unit/test_embedding_config_voyage.py --noconftest -o addopts='' -q
- .venv/bin/python -m pytest tests/misc/test_config_validation.py -o addopts='' -q
- .venv/bin/ruff check openviking/models/embedder/voyage_embedders.py openviking_cli/utils/config/embedding_config.py tests/unit/test_embedding_config_voyage.py tests/unit/test_voyage_embedder.py
Remove the trivial Voyage-specific helper and inline the output_dimension payload construction at the two call sites.

This keeps the request shape unchanged while making the embedder implementation more direct.
Copy link
Copy Markdown
Collaborator

@ZaynJarvis ZaynJarvis left a comment

Choose a reason for hiding this comment

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

lgtm, thx. pls resolve conflict and this feat shall be merged

@kfiramar
Copy link
Copy Markdown
Contributor Author

kfiramar commented Mar 16, 2026

Also added missing 'ollama' to the doctoring

Should I add it also to the docs? (ofc it is not related to Voyage - but the doctoring was a conflict so I added it as well)

@qin-ctx qin-ctx merged commit cdd0f79 into volcengine:main Mar 16, 2026
1 check passed
@github-project-automation github-project-automation bot moved this from Backlog to Done in OpenViking project Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants