UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

345 lines (291 loc) 9.18 kB
import type { Pricing } from 'model-bank'; import { describe, expect, it } from 'vitest'; import { ImageGenerationParams, computeImageCost } from './computeImageCost'; describe('computeImageCost', () => { describe('lookup pricing strategy', () => { it('should compute dall-e-3 lookup pricing correctly', () => { // Arrange - Based on actual production logs const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'lookup', unit: 'image', lookup: { pricingParams: ['quality', 'size'], prices: { standard_1024x1024: 0.04, standard_1024x1792: 0.08, standard_1792x1024: 0.08, hd_1024x1024: 0.08, hd_1024x1792: 0.12, hd_1792x1024: 0.12, }, }, }, ], }; const params: ImageGenerationParams = { quality: 'standard', size: '1024x1024', prompt: '一条边牧', }; // Act const result = computeImageCost(pricing, params, 1); // Assert - Match the production log output expect(result).toBeDefined(); expect(result?.totalCost).toBe(0.04); expect(result?.totalCredits).toBe(40000); // $0.04 * 100000 credits per dollar expect(result?.breakdown?.lookupKey).toBe('standard_1024x1024'); expect(result?.breakdown?.pricePerImage).toBe(0.04); expect(result?.breakdown?.imageCount).toBe(1); }); it('should compute lookup pricing for multiple images', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'lookup', unit: 'image', lookup: { pricingParams: ['quality', 'size'], prices: { hd_1024x1792: 0.12, }, }, }, ], }; const params: ImageGenerationParams = { quality: 'hd', size: '1024x1792', }; const result = computeImageCost(pricing, params, 3); expect(result).toBeDefined(); expect(result?.totalCost).toBe(0.36); // 0.12 * 3 expect(result?.totalCredits).toBe(360000); // $0.36 * 100000 expect(result?.breakdown?.lookupKey).toBe('hd_1024x1792'); expect(result?.breakdown?.imageCount).toBe(3); }); it('should return undefined if required lookup param is missing', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'lookup', unit: 'image', lookup: { pricingParams: ['quality', 'size'], prices: { standard_1024x1024: 0.04, }, }, }, ], }; const params: ImageGenerationParams = { quality: 'standard', // Missing 'size' parameter }; const result = computeImageCost(pricing, params, 1); expect(result).toBeUndefined(); }); it('should return undefined if lookup key has no matching price', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'lookup', unit: 'image', lookup: { pricingParams: ['quality', 'size'], prices: { standard_1024x1024: 0.04, }, }, }, ], }; const params: ImageGenerationParams = { quality: 'hd', size: '2048x2048', // No matching price for this combination }; const result = computeImageCost(pricing, params, 1); expect(result).toBeUndefined(); }); it('should return undefined if lookup has no pricingParams defined', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'lookup', unit: 'image', lookup: { // Missing pricingParams prices: { standard_1024x1024: 0.04, }, pricingParams: [], } as any, }, ], }; const params: ImageGenerationParams = { quality: 'standard', size: '1024x1024', }; const result = computeImageCost(pricing, params, 1); expect(result).toBeUndefined(); }); }); describe('fixed pricing strategy', () => { it('should compute fixed pricing correctly', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'fixed', unit: 'image', rate: 0.05, }, ], }; const params: ImageGenerationParams = { quality: 'standard', size: '512x512', }; const result = computeImageCost(pricing, params, 1); expect(result).toBeDefined(); expect(result?.totalCost).toBe(0.05); expect(result?.totalCredits).toBe(50000); // $0.05 * 100000 expect(result?.breakdown?.pricePerImage).toBe(0.05); expect(result?.breakdown?.imageCount).toBe(1); expect(result?.breakdown?.lookupKey).toBeUndefined(); }); it('should compute fixed pricing for multiple images', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'fixed', unit: 'image', rate: 0.02, }, ], }; const params: ImageGenerationParams = {}; const result = computeImageCost(pricing, params, 5); expect(result).toBeDefined(); expect(result?.totalCost).toBe(0.1); // 0.02 * 5 expect(result?.totalCredits).toBe(100000); expect(result?.breakdown?.imageCount).toBe(5); }); it('should return undefined if fixed pricing unit is not image', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'fixed', unit: 'token' as any, // Unsupported unit type rate: 0.05, }, ], }; const params: ImageGenerationParams = {}; const result = computeImageCost(pricing, params, 1); expect(result).toBeUndefined(); }); }); describe('tiered pricing strategy', () => { it('should return undefined for tiered strategy (not yet implemented)', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'tiered', unit: 'image', tiers: [ { upTo: 10, rate: 0.05 }, { upTo: 'infinity' as any, rate: 0.03 }, ], }, ], }; const params: ImageGenerationParams = {}; const result = computeImageCost(pricing, params, 1); expect(result).toBeUndefined(); }); }); describe('edge cases', () => { it('should return undefined if no imageGeneration unit found', () => { const pricing: Pricing = { units: [ { name: 'textGeneration' as any, // Different unit name strategy: 'fixed', unit: 'token' as any, rate: 0.01, }, ], }; const params: ImageGenerationParams = {}; const result = computeImageCost(pricing, params, 1); expect(result).toBeUndefined(); }); it('should return undefined for unsupported pricing strategy', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', // @ts-expect-error - Testing unsupported strategy strategy: 'unsupported_strategy', unit: 'image', }, ], }; const params: ImageGenerationParams = {}; const result = computeImageCost(pricing, params, 1); expect(result).toBeUndefined(); }); it('should handle null lookup param value', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'lookup', unit: 'image', lookup: { pricingParams: ['quality', 'size'], prices: { standard_1024x1024: 0.04, }, }, }, ], }; const params: ImageGenerationParams = { quality: null as any, // null value for testing size: '1024x1024', }; const result = computeImageCost(pricing, params, 1); expect(result).toBeUndefined(); }); it('should handle zero images', () => { const pricing: Pricing = { units: [ { name: 'imageGeneration', strategy: 'fixed', unit: 'image', rate: 0.05, }, ], }; const params: ImageGenerationParams = {}; const result = computeImageCost(pricing, params, 0); expect(result).toBeDefined(); expect(result?.totalCost).toBe(0); expect(result?.totalCredits).toBe(0); }); }); });