feat: switch embeddings from Voyage AI to Google Gemini text-embedding-004
- embedText: call Gemini REST API (768-dim) instead of Voyage (1024-dim) - Migration: drop+recreate incidents.embedding as vector(768), update match_incidents function, swap VOYAGE_API_KEY → GOOGLE_AI_API_KEY in app_settings - Settings UI: relabel to "Google AI API Key (Embeddings)" - All call sites updated (incidents POST, similar GET) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CPf5Rc8QPx6V8KLEEgfKEQ
This commit is contained in:
@@ -2,36 +2,36 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
|
||||
describe('embedText', () => {
|
||||
beforeEach(() => {
|
||||
process.env.VOYAGE_API_KEY = 'test-key'
|
||||
process.env.GOOGLE_AI_API_KEY = 'test-key'
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('returns 1024-element embedding array', async () => {
|
||||
const mockEmbedding = Array.from({ length: 1024 }, (_, i) => i / 1024)
|
||||
it('returns 768-element embedding array', async () => {
|
||||
const mockEmbedding = Array.from({ length: 768 }, (_, i) => i / 768)
|
||||
vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ data: [{ embedding: mockEmbedding }] }),
|
||||
json: () => Promise.resolve({ embedding: { values: mockEmbedding } }),
|
||||
}))
|
||||
const { embedText } = await import('@/lib/claude/embed')
|
||||
const result = await embedText('forklift hit racking in zone B')
|
||||
expect(result).toHaveLength(1024)
|
||||
expect(result).toHaveLength(768)
|
||||
expect(result[0]).toBeCloseTo(0)
|
||||
expect(result[1023]).toBeCloseTo(1023 / 1024)
|
||||
expect(result[767]).toBeCloseTo(767 / 768)
|
||||
})
|
||||
|
||||
it('throws on non-ok response', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ ok: false, status: 401 }))
|
||||
const { embedText } = await import('@/lib/claude/embed')
|
||||
await expect(embedText('test')).rejects.toThrow('Voyage embed failed: 401')
|
||||
await expect(embedText('test')).rejects.toThrow('Gemini embed failed: 401')
|
||||
})
|
||||
|
||||
it('throws when VOYAGE_API_KEY is missing', async () => {
|
||||
delete process.env.VOYAGE_API_KEY
|
||||
it('throws when GOOGLE_AI_API_KEY is missing', async () => {
|
||||
delete process.env.GOOGLE_AI_API_KEY
|
||||
vi.resetModules()
|
||||
const { embedText } = await import('@/lib/claude/embed')
|
||||
await expect(embedText('test')).rejects.toThrow('VOYAGE_API_KEY')
|
||||
await expect(embedText('test')).rejects.toThrow('GOOGLE_AI_API_KEY')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user