mirror of
https://github.com/labring/FastGPT.git
synced 2026-05-02 01:02:05 +08:00
3f4400a500
* 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>
96 lines
2.9 KiB
TypeScript
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);
|
|
});
|
|
});
|