Skip to content

fix(gemini): apply request-level taskType and title to every batched embedding input - #7884

Merged
akshaydeo merged 1 commit into
devfrom
bug-gemini-embeddings-tasktype-title-applied-onl
Oct 3, 2026
Merged

akshaydeo merged 1 commit into
devfrom
bug-gemini-embeddings-tasktype-title-applied-onl

Conversation

@akshaydeo

@akshaydeo akshaydeo commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Two independent bug fixes: (1) Gemini batch embedding requests with a request-level taskType or title (either as Gemini-native camelCase extra params or first-class snake_case fields) now correctly fan out to every requests[] entry of :batchEmbedContents and no longer leak those keys to the batch top level, where Gemini returns a 400. (2) Transcription cost calculation now carries the provider-reported usage.cost through when rebuilding BifrostLLMUsage, so the short-circuit passthrough that chat already uses works correctly for transcription responses.

Changes

  • Gemini embedding taskType/title fan-out ([Bug]: Gemini embeddings: taskType/title applied only to the first input of a batched /v1/embeddings request #7812): ToGeminiEmbeddingRequest previously assigned bifrostReq.Params.ExtraParams directly to the batch-level ExtraParams, meaning Gemini-native per-entry keys (taskType, title, documentOcr, audioTrackExtraction) were present at the top level of the batch body. With x-bf-passthrough-extra-params enabled, Gemini rejected the request with a 400. The fix clones the extra-params map, strips the per-entry keys from the batch level, and applyGeminiEmbeddingParams now promotes taskType and title from extra params onto the typed fields of each individual entry (honouring first-class fields as the winner). A sentinel list geminiPerEntryEmbeddingExtraKeys documents which keys belong per-entry.
  • Transcription provider-reported cost passthrough ([Bug]: Transcription cost ignores provider-reported usage.cost and per-second pricing is unreachable when input_tokens > 0 #7819): extractTranscriptionUsage constructed a fresh BifrostLLMUsage{} without copying u.Cost, so the provider-reported cost was silently discarded and the datasheet rate was used instead. The fix initialises the struct with Cost: u.Cost, matching the existing behaviour for chat and image responses.

Type of change

  • Bug fix

Affected areas

  • Core (Go)
  • Providers/Integrations

How to test

# Unit tests covering both fixes
cd core
go test ./providers/gemini/... -run "TestToGeminiEmbeddingRequest"

cd framework
go test ./modelcatalog/datasheet/... -run "TestCalculateCost_TranscriptionProviderComputedCostPassthrough"

For the Gemini embedding fix, run the E2E harness against a live Gemini key:

PROVIDER=gemini FEATURE="gemini-embedding-tasktype" <e2e runner>
# Tests 141.A1 (camelCase extra param) and 141.A2 (snake_case first-class field)
# Both assert taskType and title appear on every requests[] entry and are absent at the batch top level.

Breaking changes

  • No

Related issues

Closes #7812
Closes #7819

Security considerations

None. No auth, secrets, or PII involved.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai

coderabbitai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: maximhq/bifrost/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 5be909e1-8eaa-40bd-93df-1996625edb21
📥 Commits

Reviewing files that changed from the base of the PR and between 0d25eca and b338e10.

⛔ Files ignored due to path filters (1)
  • core/go.sum is excluded by !**/*.sum
📒 Files selected for processing (3)
  • core/providers/gemini/embedding.go
  • core/providers/gemini/embedding_multimodal_test.go
  • tests/e2e/api/collections/provider-harness.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.


📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Fixed Gemini embedding requests so request-level task type and title are applied to every item in a batch.
    • These settings now work when provided in camelCase or snake_case, and are sent with each embedding request rather than at the batch level. This ensures all generated embeddings in a batch use the intended task and title.

Walkthrough

The Gemini embedding converter now assigns request-level taskType and title values to each batch entry. Tests cover native extra parameters, first-class parameters, and camelCase and snake_case API inputs.

Changes

Gemini Embedding Parameters

Layer / File(s) Summary
Per-entry parameter conversion
core/providers/gemini/embedding.go, core/providers/gemini/embedding_multimodal_test.go, tests/e2e/api/collections/provider-harness.json
The converter clones batch extras and removes per-entry keys from the batch-level map. It applies string-valued taskType and title extras to each entry when the corresponding first-class field is nil. Tests cover extra parameters, first-class fields, and camelCase and snake_case API inputs.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to b338e

This change applies request-level task type and title to every Gemini batched embedding input. No merge-blocking risk was identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 2 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The current PR description links #7812 and #7819. For #7812, the Gemini converter fans taskType and title out to each batch entry, gives first-class fields precedence, and removes per-entry keys f…
Out of Scope Changes check ✅ Passed The Gemini embedding changes address #7812, and the transcription cost change addresses #7819. Both are within the current PR description. No unrelated change is established. Closed issue #123 supplie…
Title check ✅ Passed The title clearly and concisely describes the main change: applying request-level taskType and title to every batched Gemini embedding input.
Description check ✅ Passed The description is mostly complete. It includes the summary, changes, type of change, affected areas, test steps, breaking-change status, related issues, security considerations, and checklist. The om…
Full details: Docstring Coverage

Explanation

Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 2 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@akshaydeo
akshaydeo marked this pull request as ready for review October 3, 2026 07:06

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@coderabbitai
coderabbitai Bot requested a review from TejasGhatte October 3, 2026 07:08
extractTranscriptionUsage builds a new BifrostLLMUsage for pricing and
did not copy TranscriptionUsage.Cost, so the provider-cost short circuit
in calculateBaseCost never ran for transcription. The request was priced
from the datasheet instead, which gives 0 for a per-second priced model
whose provider also reports prompt tokens (OpenRouter voxtral).

Copy the cost over, as responsesUsageToBifrostUsage already does.

Changes:
- framework/modelcatalog/datasheet/cost.go - carry the provider cost into the pricing usage
- framework/modelcatalog/datasheet/cost_test.go - regression test for transcription and transcription stream responses
- framework/changelog.md - changelog entry

Fixes #7819
@akshaydeo
akshaydeo force-pushed the bug-gemini-embeddings-tasktype-title-applied-onl branch from c88fadd to b338e10 Compare October 3, 2026 07:10
@akshaydeo akshaydeo changed the title [fix]: use provider-reported cost for transcription pricing (#7825) fix(gemini): apply request-level taskType and title to every batched embedding input Oct 3, 2026

akshaydeo commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Oct 3, 7:57 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Oct 3, 7:57 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo merged commit e8b579f into dev Oct 3, 2026
15 checks passed
@akshaydeo
akshaydeo deleted the bug-gemini-embeddings-tasktype-title-applied-onl branch October 3, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants