Skip to content

fix: send Voyage output_dimension on embedding requests#866

Closed
100yenadmin wants to merge 1 commit into
garrytan:masterfrom
electricsheephq:codex/voyage-output-dimension-wire-fix
Closed

fix: send Voyage output_dimension on embedding requests#866
100yenadmin wants to merge 1 commit into
garrytan:masterfrom
electricsheephq:codex/voyage-output-dimension-wire-fix

Conversation

@100yenadmin

@100yenadmin 100yenadmin commented May 11, 2026

Copy link
Copy Markdown
Contributor

TL;DR

Fixes Voyage 2048-dimensional embeddings by passing dimensions into the AI SDK, then letting GBrain's existing Voyage fetch shim translate that to Voyage's real wire field, output_dimension. Without this, GBrain can initialize a vector(2048) brain but the first Voyage embed request omits the dimension instruction and receives the wrong vector width.

flowchart LR
  A["embedding_dimensions=2048"] --> B["dimsProviderOptions"]
  B --> C["AI SDK openai-compatible"]
  C --> D["voyageCompatFetch"]
  D --> E["Voyage /embeddings"]

  B -->|"SDK key"| C
  C -->|"dimensions"| D
  D -->|"output_dimension"| E
Loading

What Changed

  • Changes Voyage OpenAI-compatible provider options from output_dimension to SDK-forwarded dimensions.
  • Keeps the existing voyageCompatFetch rewrite as the single wire-compatibility point.
  • Adds voyage-4-nano to the flexible-dimension Voyage model set.
  • Adds a wire-level regression test proving the actual Voyage request body contains output_dimension: 2048.

Why This Is The Small Fix

GBrain already has the right architecture: provider dimension knowledge lives in dims.ts, and Voyage wire differences live in the gateway fetch wrapper. The bug is just that dims.ts was bypassing the SDK contract by passing Voyage's final wire key too early.

This PR keeps the boundary intact:

  • dims.ts: says "this model needs dimensions"
  • AI SDK: receives the supported dimensions option
  • voyageCompatFetch: translates to Voyage's output_dimension

Non-Goals

  • No schema changes.
  • No HNSW changes.
  • No pricing/default-dimension changes.
  • No changes to unrelated OpenAI-compatible providers.

Validation

  • git diff --check
  • Attempted focused local test: bun test test/ai/gateway.test.ts
    • Could not run in the fresh upstream worktree because dependencies are not installed there: Cannot find package 'ai'.
    • Full validation should run in GitHub Actions on this PR branch.

@100yenadmin

100yenadmin commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

Validation update from the refreshed branch:

  • git diff --check passed
  • bun install --frozen-lockfile completed in the PR worktree
  • bun test test/ai/gateway.test.ts passed in /Volumes/LEXAR/repos/gbrain-upstream-prs/voyage: 23 pass / 0 fail

The focused test includes the wire-level regression that verifies the actual Voyage embedding request body sends output_dimension: 2048.

@100yenadmin

Copy link
Copy Markdown
Contributor Author

@garrytan @garrytan-agents

@garrytan

Copy link
Copy Markdown
Owner

Thanks @100yenadmin — this catch is real and the fix is the right shape (move dim routing through the SDK-supported dimensions key, let voyageCompatFetch translate to Voyage's wire field).

Re-landing this as #962 on upstream with your commit preserved verbatim (commit ee90709e, author Eva <eva@100yen.org>). The reason for re-opening rather than landing here: the maintainerCanModify flag doesn't actually grant cross-fork push access from this account — both HTTPS and SSH hit 403 trying to push to electricsheephq/eva-brain. To land your fix + a follow-up fixup atomically in a single merge, the cleanest path is upstream-side.

The follow-up fixup on top (commit 8b02e238): voyage-4-nano is an open-weight Voyage model with fixed 1024-dim — Voyage's hosted API rejects output_dimension for it. Adversarial Codex review during PR evaluation flagged it; Voyage's docs confirmed only seven models (voyage-4-large, voyage-4, voyage-4-lite, voyage-3-large, voyage-3.5, voyage-3.5-lite, voyage-code-3) accept the parameter. The fixup drops nano from the allowlist, tightens the recipe docstring that misled the addition, and flips the test to a negative regression pin so a future contributor can't silently re-add it.

Closing this in favor of #962. Your authorship stays on the core commit. Appreciate the contribution.

@garrytan garrytan closed this May 13, 2026
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