Files
metapi/src/server/services/proxyUsageFallbackService.test.ts
T

197 lines
5.4 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
extractSelfLogItems,
findBestSelfLogMatch,
shouldLookupSelfLog,
type SelfLogItem,
} from './proxyUsageFallbackService.js';
describe('proxyUsageFallbackService', () => {
it('extracts logs from nested /api/log/self payload', () => {
const payload = {
success: true,
data: {
data: [
{
model_name: 'gpt-4o',
prompt_tokens: 120,
completion_tokens: 80,
quota: 3300,
created_at: 1_700_000_123,
request_time: 1450,
},
],
},
};
const logs = extractSelfLogItems(payload);
expect(logs).toEqual([
{
modelName: 'gpt-4o',
tokenName: '',
promptTokens: 120,
completionTokens: 80,
totalTokens: 200,
quota: 3300,
createdAtMs: 1_700_000_123_000,
requestTimeMs: 1450,
billingMeta: null,
},
]);
});
it('extracts cache billing metadata from self-log other payload', () => {
const payload = {
success: true,
data: {
items: [
{
model_name: 'claude-haiku-4-5-20251001',
token_name: 'anyrouter',
prompt_tokens: 146638,
completion_tokens: 172,
quota: 41528,
created_at: 1_772_790_705,
request_time: 1700,
other: JSON.stringify({
cache_creation_ratio: 1.25,
cache_creation_tokens: 945,
cache_ratio: 0.1,
cache_tokens: 145692,
completion_ratio: 5,
group_ratio: 1,
model_ratio: 2.5,
}),
},
],
},
};
const logs = extractSelfLogItems(payload);
expect(logs[0]).toMatchObject({
modelName: 'claude-haiku-4-5-20251001',
tokenName: 'anyrouter',
promptTokens: 146638,
completionTokens: 172,
quota: 41528,
billingMeta: {
cacheReadTokens: 145692,
cacheCreationTokens: 945,
cacheRatio: 0.1,
cacheCreationRatio: 1.25,
completionRatio: 5,
groupRatio: 1,
modelRatio: 2.5,
},
});
});
it('matches best log by model + time window + request time', () => {
const logs: SelfLogItem[] = [
{
modelName: 'gpt-4o',
tokenName: 'default',
promptTokens: 10,
completionTokens: 5,
totalTokens: 15,
quota: 1000,
createdAtMs: 1_700_000_000_000,
requestTimeMs: 800,
},
{
modelName: 'gpt-4o',
tokenName: 'default',
promptTokens: 200,
completionTokens: 100,
totalTokens: 300,
quota: 4500,
createdAtMs: 1_700_000_007_000,
requestTimeMs: 3100,
},
{
modelName: 'gpt-4o-mini',
tokenName: 'default',
promptTokens: 999,
completionTokens: 1,
totalTokens: 1000,
quota: 9999,
createdAtMs: 1_700_000_007_000,
requestTimeMs: 3100,
},
];
const matched = findBestSelfLogMatch(logs, {
modelName: 'gpt-4o',
requestStartedAtMs: 1_700_000_004_000,
requestEndedAtMs: 1_700_000_008_200,
localLatencyMs: 3200,
});
expect(matched).toEqual(logs[1]);
});
it('returns null when no safe match exists', () => {
const logs: SelfLogItem[] = [
{
modelName: 'gpt-4o',
tokenName: 'default',
promptTokens: 120,
completionTokens: 80,
totalTokens: 200,
quota: 3300,
createdAtMs: 1_700_000_123_000,
requestTimeMs: 1450,
},
];
const matched = findBestSelfLogMatch(logs, {
modelName: 'gpt-4o',
requestStartedAtMs: 1_700_010_000_000,
requestEndedAtMs: 1_700_010_004_000,
localLatencyMs: 4000,
});
expect(matched).toBeNull();
});
it('matches provider-prefixed model names', () => {
const logs: SelfLogItem[] = [
{
modelName: 'z-ai/glm4.7',
tokenName: 'sys_playground',
promptTokens: 1095,
completionTokens: 2179,
totalTokens: 3274,
quota: 1890000,
createdAtMs: 1_772_024_884_000,
requestTimeMs: 59_000,
},
];
const matched = findBestSelfLogMatch(logs, {
modelName: 'glm4.7',
tokenName: 'windhub',
requestStartedAtMs: 1_772_024_825_000,
requestEndedAtMs: 1_772_024_884_500,
localLatencyMs: 59_000,
});
expect(matched).toEqual(logs[0]);
});
it('always enables self-log lookup for done-hub/one-hub', () => {
expect(shouldLookupSelfLog('done-hub', { promptTokens: 12, completionTokens: 8, totalTokens: 20 })).toBe(true);
expect(shouldLookupSelfLog('one-hub', { promptTokens: 1, completionTokens: 1, totalTokens: 2 })).toBe(true);
});
it('only enables self-log lookup for new-api when usage is missing', () => {
expect(shouldLookupSelfLog('new-api', { promptTokens: 0, completionTokens: 0, totalTokens: 0 })).toBe(true);
expect(shouldLookupSelfLog('new-api', { promptTokens: 12, completionTokens: 3, totalTokens: 15 })).toBe(false);
});
it('always enables self-log lookup for anyrouter to recover exact billing metadata', () => {
expect(shouldLookupSelfLog('anyrouter', { promptTokens: 0, completionTokens: 0, totalTokens: 0 })).toBe(true);
expect(shouldLookupSelfLog('anyrouter', { promptTokens: 12, completionTokens: 3, totalTokens: 15 })).toBe(true);
});
});