import { describe, expect, it, vi } from 'vitest'; import { createEmbeddingClientFromEnvironment, embeddingEndpoint, EmbeddingClientError, OpenAiCompatibleEmbeddingClient } from '../../server/regulatory/embedding-client'; describe('regulatory embedding client', () => { it('allows loopback HTTP, requires remote HTTPS, and requires explicit dimensions', () => { expect(embeddingEndpoint('https://litellm.work.example/v1').href).toBe('https://litellm.work.example/v1/embeddings'); expect(embeddingEndpoint('http://127.0.0.1:8080/v1').href).toBe('http://127.0.0.1:8080/v1/embeddings'); expect(() => embeddingEndpoint('http://litellm.work.example/v1')).toThrow(/HTTPS/); expect(() => createEmbeddingClientFromEnvironment({ ASSESSOR_RAG_EMBEDDING_BASE_URL: 'https://litellm.work.example/v1', ASSESSOR_RAG_EMBEDDING_MODEL: 'multilingual-model', ASSESSOR_RAG_EMBEDDING_API_KEY: 'secret' })).toThrow(/DIMENSIONS is required/); }); it('requests a shortened dimension only when explicitly configured', async () => { const bodies: unknown[] = []; const fetcher = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => { bodies.push(JSON.parse(String(init?.body))); return new Response(JSON.stringify({ data: [{ index: 0, embedding: Array(64).fill(0) }] }), { status: 200 }); }); const client = createEmbeddingClientFromEnvironment({ ASSESSOR_RAG_EMBEDDING_BASE_URL: 'https://litellm.work.example/v1', ASSESSOR_RAG_EMBEDDING_MODEL: 'text-embedding-3-large', ASSESSOR_RAG_EMBEDDING_API_KEY: 'secret', ASSESSOR_RAG_EMBEDDING_DIMENSIONS: '64', ASSESSOR_RAG_EMBEDDING_REQUEST_DIMENSIONS: 'true' }, fetcher); await client.embed(['Synthetic text']); expect(bodies).toEqual([{ model: 'text-embedding-3-large', input: ['Synthetic text'], encoding_format: 'float', dimensions: 64 }]); }); it('returns embeddings in provider index order without exposing the API key', async () => { const fetcher = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => { expect(init?.redirect).toBe('error'); expect(new Headers(init?.headers).get('authorization')).toBe('Bearer secret'); expect(JSON.parse(String(init?.body))).toEqual({ model: 'multilingual-model', input: ['Deutsch', 'English'], encoding_format: 'float' }); return new Response(JSON.stringify({ data: [ { index: 1, embedding: [0, 1] }, { index: 0, embedding: [1, 0] } ] }), { status: 200 }); }); const client = new OpenAiCompatibleEmbeddingClient({ endpoint: new URL('https://litellm.work.example/v1/embeddings'), model: 'multilingual-model', apiKey: 'secret', dimensions: 2, timeoutMs: 1_000, fetcher }); await expect(client.embed(['Deutsch', 'English'])).resolves.toEqual([[1, 0], [0, 1]]); expect(fetcher).toHaveBeenCalledOnce(); }); it('rejects incompatible vector dimensions', async () => { const client = new OpenAiCompatibleEmbeddingClient({ endpoint: new URL('https://litellm.work.example/v1/embeddings'), model: 'multilingual-model', apiKey: 'secret', dimensions: 3, timeoutMs: 1_000, fetcher: async () => new Response(JSON.stringify({ data: [{ index: 0, embedding: [1, 0] }] }), { status: 200 }) }); await expect(client.embed(['query'])).rejects.toMatchObject({ code: 'embedding_invalid_dimensions' } satisfies Partial); }); });