Skip to content

feat: Gemini embedding support via GEMINI_API_KEY env var (zero-config, free tier)#89

Open
flychicken067 wants to merge 2 commits intogarrytan:masterfrom
flychicken067:gemini-embedding-support
Open

feat: Gemini embedding support via GEMINI_API_KEY env var (zero-config, free tier)#89
flychicken067 wants to merge 2 commits intogarrytan:masterfrom
flychicken067:gemini-embedding-support

Conversation

@flychicken067
Copy link
Copy Markdown

What this does

Adds Gemini embedding support as a zero-config free alternative to OpenAI.
Set GEMINI_API_KEY and GBrain uses Gemini automatically — no config file changes, no gbrain init flags.

Why env-var auto-detection instead of config flags

The simplest path to a working brain for users without an OpenAI key:

export GEMINI_API_KEY=your_key   # from aistudio.google.com — free
gbrain embed --stale              # just works
gbrain query "your question"      # just works

No --provider flags. No config file edits. Existing OpenAI users are unaffected.

Changes (2 files only)

src/core/embedding.ts — multi-provider with auto-detection:

  • Priority: GEMINI_API_KEYOPENAI_API_KEY → clear error with link to get a key
  • gemini-embedding-001 returns 3072 dims by default; sliced to 1536 — no schema changes
  • Exponential backoff (4s base, 120s cap, 5 retries) matching OpenAI path
  • Free tier: 1500 req/day, sufficient for personal knowledge bases

src/core/search/hybrid.ts — fix key detection:

  • Was: if (!process.env.OPENAI_API_KEY) (skipped vector search with Gemini key)
  • Now: if (!process.env.OPENAI_API_KEY && !process.env.GEMINI_API_KEY)

Real-world test

Tested on a 48-page Chinese/English knowledge base:

  • English query → returns Chinese article as top result via semantic similarity
  • Cross-language search works because Gemini embedding space is language-agnostic
  • gbrain doctor passes, 100% embedding coverage
$ gbrain query "knowledge loss when employees leave"
[0.0333] article_17 -- 字节跳动的「飞书知识库」解决不了一件事...

English question surfaces Chinese article. This is the core value of semantic over keyword search.

Relation to #58

PR #58 takes a config-based approach (--provider, outputDimensionality param).
This PR takes an env-var approach (detect key, auto-select provider).
Both maintain 1536-dim compatibility. Different UX tradeoffs — happy to consolidate if preferred.

Verification

export GEMINI_API_KEY=your_key
gbrain embed --stale
gbrain query "test question"
gbrain doctor  # should show 100% coverage

Get a free Gemini key: https://aistudio.google.com/apikey

🤖 Generated with Claude Code

Ivan and others added 2 commits April 12, 2026 14:29
- embedding.ts: auto-detect GEMINI_API_KEY or OPENAI_API_KEY
- hybrid.ts: fix key check to include GEMINI_API_KEY
- gemini-embedding-001 at 1536 dims, no schema changes needed
- Free tier: 1500 req/day, sufficient for personal knowledge bases

Tested on 48-page knowledge base. Cross-language search works:
English query finds Chinese notes via semantic similarity.
Required peer dependency for GEMINI_API_KEY auto-detection path.
Free tier: 1500 req/day via aistudio.google.com

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@prasadus92
Copy link
Copy Markdown

+1, applied this locally on v0.12.0 and confirmed it works cleanly.

Setup on Alfred (Mac Mini dev box):

gh pr checkout 89 -R garrytan/gbrain
bun install
GEMINI_API_KEY=AIza... bun ./src/core/embedding.ts
# → dim: 1536 ✓

Why this matters for us:

  • Solo-founder budget sensitivity on pay-per-token inference (OpenAI / Anthropic)
  • We already have GEMINI_API_KEY wired for Hermes Agent; zero extra config to share the same free-tier key with gbrain
  • 1536-dim slice preserves the existing schema — no DB migration, works with PGLite local brain out of the box

Minor observation (not blocking): the 1536 dims, free tier comment on line 5 is slightly ambiguous — the key docstring claim is that gemini-embedding-001 returns 3072 and we slice to 1536 to match the schema, which is what the code actually does (line 58). Worth a small clarification in the comment block so the "1536 dims" line reads as "we slice 3072→1536 for schema compat" rather than "the model returns 1536 natively." Not worth delaying a merge over.

Would love to see this land — there are 8+ open PRs in this area (#58, #59, #99, #134, #147, #150, #172, #178) which suggests real demand for multi-provider embeddings. The zero-config env-var approach in this PR is the cleanest UX of the bunch.

Happy to help with any reviewer asks.

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