Skip to main content
Glama
api-contract.test.ts4.39 kB
import { describe, it, expect, beforeAll } from 'vitest'; /** * API Contract Tests * These tests validate that our implementation matches the Venice API specification. * They would have caught the width/height vs size parameter bug. */ const VENICE_API_BASE = 'https://api.venice.ai/api/v1'; const API_KEY = process.env.VENICE_API_KEY; describe('Venice API Contract Tests', () => { const skipIfNoKey = !API_KEY || API_KEY === 'test-api-key'; describe('Image Generation API Contract', () => { it('should use "size" parameter format (not width/height)', async () => { // This test validates the correct parameter format // Venice API expects: { size: "1024x1024" } // NOT: { width: 1024, height: 1024 } const correctPayload = { model: 'fluently-xl', prompt: 'test', size: '1024x1024', // ✅ Correct format }; const incorrectPayload = { model: 'fluently-xl', prompt: 'test', width: 1024, // ❌ Wrong format height: 1024, // ❌ Wrong format }; // Validate our payload structure expect(correctPayload).toHaveProperty('size'); expect(correctPayload).not.toHaveProperty('width'); expect(correctPayload).not.toHaveProperty('height'); // Size should be in WxH format expect(correctPayload.size).toMatch(/^\d+x\d+$/); }); it.skipIf(skipIfNoKey)('should successfully call image generation with correct format', async () => { const response = await fetch(`${VENICE_API_BASE}/images/generations`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'fluently-xl', prompt: 'A simple red circle on white background', size: '512x512', }), }); expect(response.ok).toBe(true); const data = await response.json(); expect(data).toHaveProperty('data'); expect(Array.isArray(data.data)).toBe(true); }); it.skipIf(skipIfNoKey)('should fail with width/height parameters (proving they are wrong)', async () => { const response = await fetch(`${VENICE_API_BASE}/images/generations`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'fluently-xl', prompt: 'test', width: 512, // Wrong! height: 512, // Wrong! }), }); // This should fail because width/height are not valid parameters expect(response.ok).toBe(false); }); }); describe('Chat API Contract', () => { it('should have correct message format', () => { const correctPayload = { model: 'llama-3.3-70b', messages: [ { role: 'user', content: 'Hello' } ], }; expect(correctPayload.messages).toBeInstanceOf(Array); expect(correctPayload.messages[0]).toHaveProperty('role'); expect(correctPayload.messages[0]).toHaveProperty('content'); }); it.skipIf(skipIfNoKey)('should successfully call chat completion', async () => { const response = await fetch(`${VENICE_API_BASE}/chat/completions`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'llama-3.3-70b', messages: [{ role: 'user', content: 'Say "test" and nothing else' }], max_tokens: 10, }), }); expect(response.ok).toBe(true); const data = await response.json(); expect(data).toHaveProperty('choices'); }); }); describe('TTS API Contract', () => { it.skipIf(skipIfNoKey)('should successfully call text-to-speech', async () => { const response = await fetch(`${VENICE_API_BASE}/audio/speech`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'tts-kokoro', input: 'Test', voice: 'af_sky', }), }); expect(response.ok).toBe(true); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/georgeglarson/venice-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server