Files
FastGPT/test/cases/service/support/wallet/usage/utils.test.ts
T
Archer 3f4400a500 V4.14.10 dev (#6674)
* feat: model config with brand-new price calculate machanism (#6616)

* fix: image read and json error (Agent) (#6502)

* fix:
1.image read
2.JSON parsing error

* dataset cite and pause

* perf: plancall second parse

* add test

---------

Co-authored-by: archer <545436317@qq.com>

* master message

* remove invalid code

* wip: model config

* feat: model config with brand-new price calculate machanism

* merge main branch

* ajust calculate way

* ajust priceTiers resolve procession

* perf: price config code

* fix: default price

* fix: test

* fix: comment

* fix test

---------

Co-authored-by: YeYuheng <57035043+YYH211@users.noreply.github.com>
Co-authored-by: archer <545436317@qq.com>

* wip: fix modal UI (#6634)

* wip: fix modal UI

* fix: maxInputToken set

* chore: add price unit for non llm models

* chore: replace question mark icon with beta tag (#6672)

* feat:rerank too long; fix:rerank ui(agent),embedding returns 0 (#6663)

* feat:rerank too long; fix:rerank ui(agent),embedding returns 0

* rerank

* fix:rerank function

* perf: rerank code

* fix rerank

* perf: model price ui

---------

Co-authored-by: archer <545436317@qq.com>

* remove llmtype field

* revert model init

* fix: filed

* fix: model select filter

* perf: multiple selector render

* remove invalid checker

* remove invalid i18n

* perf: model selector tip

* perf: model selector tip

* fix cr

* limit pnpm version

* fix: i18n

* fix action

* set default mintoken

* update i18n

* perf: usage push

* fix:rerank model ui (#6677)

* fix: tier match error

* fix: testr

---------

Co-authored-by: Ryo <whoeverimf5@gmail.com>
Co-authored-by: YeYuheng <57035043+YYH211@users.noreply.github.com>
2026-03-30 10:05:42 +08:00

96 lines
2.9 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import { formatModelChars2Points } from '@fastgpt/service/support/wallet/usage/utils';
// mock findAIModel,避免依赖全局 model map
const mockModels: Record<string, any> = {
'gpt-4': {
name: 'GPT-4',
model: 'gpt-4',
charsPointsPrice: 0,
inputPrice: 3,
outputPrice: 6
},
'gpt-3.5': {
name: 'GPT-3.5',
model: 'gpt-3.5',
charsPointsPrice: 2
},
'tiered-model': {
name: 'Tiered',
model: 'tiered-model',
priceTiers: [
{ maxInputTokens: 1, inputPrice: 1, outputPrice: 2 },
{ inputPrice: 5, outputPrice: 10 }
]
}
};
vi.mock('@fastgpt/service/core/ai/model', () => ({
findAIModel: (model: string) => mockModels[model]
}));
describe('formatModelChars2Points', () => {
it('should return 0 points and empty name when model not found', () => {
const result = formatModelChars2Points({ model: 'non-existent' });
expect(result).toEqual({ totalPoints: 0, modelName: '' });
});
it('should return 0 points and empty name when model is empty string', () => {
const result = formatModelChars2Points({ model: '' });
expect(result).toEqual({ totalPoints: 0, modelName: '' });
});
it('should calculate points with legacy input/output pricing', () => {
const result = formatModelChars2Points({
model: 'gpt-4',
inputTokens: 1000,
outputTokens: 500
});
expect(result.modelName).toBe('GPT-4');
// inputPrice:3 * (1000/1000) + outputPrice:6 * (500/1000) = 3 + 3 = 6
expect(result.totalPoints).toBe(6);
});
it('should calculate points with comprehensive price', () => {
const result = formatModelChars2Points({
model: 'gpt-3.5',
inputTokens: 2000,
outputTokens: 1000
});
expect(result.modelName).toBe('GPT-3.5');
// charsPointsPrice:2 → inputPrice=outputPrice=2
// 2 * (2000/1000) + 2 * (1000/1000) = 4 + 2 = 6
expect(result.totalPoints).toBe(6);
});
it('should use default 0 tokens when not provided', () => {
const result = formatModelChars2Points({ model: 'gpt-4' });
expect(result.modelName).toBe('GPT-4');
expect(result.totalPoints).toBe(0);
});
it('should support custom multiple parameter', () => {
const result = formatModelChars2Points({
model: 'gpt-4',
inputTokens: 500,
outputTokens: 500,
multiple: 500
});
expect(result.modelName).toBe('GPT-4');
// inputPrice:3 * (500/500) + outputPrice:6 * (500/500) = 3 + 6 = 9
expect(result.totalPoints).toBe(9);
});
it('should calculate points with price tiers', () => {
const result = formatModelChars2Points({
model: 'tiered-model',
inputTokens: 2000,
outputTokens: 100
});
expect(result.modelName).toBe('Tiered');
// inputTokens:200 匹配第二梯度 (inputPrice:5, outputPrice:10)
// 5 * (2000/1000) + 10 * (100/1000) = 10 + 1 = 11
expect(result.totalPoints).toBe(11);
});
});