mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-03-09 17:42:38 +01:00
🪢 chore: Consolidate Pricing and Tx Imports After tx.js Module Removal (#12086)
* 🧹 chore: resolve imports due to rebase
* chore: Update model mocks in unit tests for consistency
- Consolidated model mock implementations across various test files to streamline setup and reduce redundancy.
- Removed duplicate mock definitions for `getMultiplier` and `getCacheMultiplier`, ensuring a unified approach in `recordCollectedUsage.spec.js`, `openai.spec.js`, `responses.unit.spec.js`, and `abortMiddleware.spec.js`.
- Enhanced clarity and maintainability of test files by aligning mock structures with the latest model updates.
* fix: Safeguard token credit checks in transaction tests
- Updated assertions in `transaction.spec.ts` to handle potential null values for `updatedBalance` by using optional chaining.
- Enhanced robustness of tests related to token credit calculations, ensuring they correctly account for scenarios where the balance may not be found.
* chore: transaction methods with bulk insert functionality
- Introduced `bulkInsertTransactions` method in `transaction.ts` to facilitate batch insertion of transaction documents.
- Updated test file `transactions.bulk-parity.spec.ts` to utilize new pricing function assignments and handle potential null values in calculations, improving test robustness.
- Refactored pricing function initialization for clarity and consistency.
* refactor: Enhance type definitions and introduce new utility functions for model matching
- Added `findMatchingPattern` and `matchModelName` utility functions to improve model name matching logic in transaction methods.
- Updated type definitions for `findMatchingPattern` to accept a more specific tokensMap structure, enhancing type safety.
- Refactored `dbMethods` initialization in `transactions.bulk-parity.spec.ts` to include the new utility functions, improving test clarity and functionality.
* refactor: Update database method imports and enhance transaction handling
- Refactored `abortMiddleware.js` to utilize centralized database methods for message handling and conversation retrieval, improving code consistency.
- Enhanced `bulkInsertTransactions` in `transaction.ts` to handle empty document arrays gracefully and added error logging for better debugging.
- Updated type definitions in `transactions.ts` to enforce stricter typing for token types, enhancing type safety across transaction methods.
- Improved test setup in `transactions.bulk-parity.spec.ts` by refining pricing function assignments and ensuring robust handling of potential null values.
* refactor: Update database method references and improve transaction multiplier handling
- Refactored `client.js` to update database method references for `bulkInsertTransactions` and `updateBalance`, ensuring consistency in method usage.
- Enhanced transaction multiplier calculations in `transaction.spec.ts` to provide fallback values for write and read multipliers, improving robustness in cost calculations across structured token spending tests.
This commit is contained in:
parent
8fafda47c2
commit
d24fe17a4b
17 changed files with 123 additions and 427 deletions
|
|
@ -14,10 +14,12 @@
|
|||
import mongoose from 'mongoose';
|
||||
import { MongoMemoryServer } from 'mongodb-memory-server';
|
||||
import {
|
||||
tokenValues,
|
||||
CANCEL_RATE,
|
||||
createMethods,
|
||||
balanceSchema,
|
||||
transactionSchema,
|
||||
premiumTokenValues,
|
||||
} from '@librechat/data-schemas';
|
||||
import type { PricingFns, TxMetadata } from './transactions';
|
||||
import {
|
||||
|
|
@ -26,6 +28,26 @@ import {
|
|||
prepareTokenSpend,
|
||||
} from './transactions';
|
||||
|
||||
/** Inlined from packages/data-schemas/src/methods/test-helpers.ts — keep in sync */
|
||||
function findMatchingPattern(
|
||||
modelName: string,
|
||||
tokensMap: Record<string, number | Record<string, number>>,
|
||||
): string | undefined {
|
||||
const keys = Object.keys(tokensMap);
|
||||
const lowerModelName = modelName.toLowerCase();
|
||||
for (let i = keys.length - 1; i >= 0; i--) {
|
||||
if (lowerModelName.includes(keys[i])) {
|
||||
return keys[i];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Inlined from packages/data-schemas/src/methods/test-helpers.ts — keep in sync */
|
||||
function matchModelName(modelName: string, _endpoint?: string): string | undefined {
|
||||
return typeof modelName === 'string' ? modelName : undefined;
|
||||
}
|
||||
|
||||
jest.mock('@librechat/data-schemas', () => {
|
||||
const actual = jest.requireActual('@librechat/data-schemas');
|
||||
return {
|
||||
|
|
@ -34,29 +56,23 @@ jest.mock('@librechat/data-schemas', () => {
|
|||
};
|
||||
});
|
||||
|
||||
// Real pricing functions from api/models/tx.js — same ones the legacy path uses
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
const {
|
||||
getMultiplier,
|
||||
getCacheMultiplier,
|
||||
tokenValues,
|
||||
premiumTokenValues,
|
||||
} = require('../../../../api/models/tx.js');
|
||||
/* eslint-enable @typescript-eslint/no-require-imports */
|
||||
|
||||
const pricing: PricingFns = { getMultiplier, getCacheMultiplier };
|
||||
|
||||
let mongoServer: MongoMemoryServer;
|
||||
let Transaction: mongoose.Model<unknown>;
|
||||
let Balance: mongoose.Model<unknown>;
|
||||
let dbMethods: ReturnType<typeof createMethods>;
|
||||
let pricing: PricingFns;
|
||||
let getMultiplier: ReturnType<typeof createMethods>['getMultiplier'];
|
||||
let getCacheMultiplier: ReturnType<typeof createMethods>['getCacheMultiplier'];
|
||||
|
||||
beforeAll(async () => {
|
||||
mongoServer = await MongoMemoryServer.create();
|
||||
await mongoose.connect(mongoServer.getUri());
|
||||
Transaction = mongoose.models.Transaction || mongoose.model('Transaction', transactionSchema);
|
||||
Balance = mongoose.models.Balance || mongoose.model('Balance', balanceSchema);
|
||||
dbMethods = createMethods(mongoose);
|
||||
dbMethods = createMethods(mongoose, { matchModelName, findMatchingPattern });
|
||||
getMultiplier = dbMethods.getMultiplier;
|
||||
getCacheMultiplier = dbMethods.getCacheMultiplier;
|
||||
pricing = { getMultiplier, getCacheMultiplier };
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
|
|
@ -536,8 +552,13 @@ describe('Multi-entry batch parity', () => {
|
|||
const premiumCompletionRate = (premiumTokenValues as Record<string, Record<string, number>>)[
|
||||
model
|
||||
].completion;
|
||||
const writeMultiplier = getCacheMultiplier({ model, cacheType: 'write' });
|
||||
const readMultiplier = getCacheMultiplier({ model, cacheType: 'read' });
|
||||
const promptMultiplier = getMultiplier({
|
||||
model,
|
||||
tokenType: 'prompt',
|
||||
inputTokenCount: totalInput,
|
||||
});
|
||||
const writeMultiplier = getCacheMultiplier({ model, cacheType: 'write' }) ?? promptMultiplier;
|
||||
const readMultiplier = getCacheMultiplier({ model, cacheType: 'read' }) ?? promptMultiplier;
|
||||
|
||||
const expectedPromptCost =
|
||||
tokenUsage.promptTokens.input * premiumPromptRate +
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@ import type { TCustomConfig, TTransactionsConfig } from 'librechat-data-provider
|
|||
import type { TransactionData } from '@librechat/data-schemas';
|
||||
import type { EndpointTokenConfig } from '~/types/tokens';
|
||||
|
||||
type TokenType = 'prompt' | 'completion';
|
||||
|
||||
interface GetMultiplierParams {
|
||||
valueKey?: string;
|
||||
tokenType?: string;
|
||||
tokenType?: TokenType;
|
||||
model?: string;
|
||||
endpointTokenConfig?: EndpointTokenConfig;
|
||||
inputTokenCount?: number;
|
||||
|
|
@ -34,14 +36,14 @@ interface BaseTxData {
|
|||
}
|
||||
|
||||
interface StandardTxData extends BaseTxData {
|
||||
tokenType: string;
|
||||
tokenType: TokenType;
|
||||
rawAmount: number;
|
||||
inputTokenCount?: number;
|
||||
valueKey?: string;
|
||||
}
|
||||
|
||||
interface StructuredTxData extends BaseTxData {
|
||||
tokenType: string;
|
||||
tokenType: TokenType;
|
||||
inputTokens?: number;
|
||||
writeTokens?: number;
|
||||
readTokens?: number;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,8 @@
|
|||
/** Configuration object mapping model keys to their respective prompt, completion rates, and context limit
|
||||
*
|
||||
* Note: the [key: string]: unknown is not in the original JSDoc typedef in /api/typedefs.js, but I've included it since
|
||||
* getModelMaxOutputTokens calls getModelTokenValue with a key of 'output', which was not in the original JSDoc typedef,
|
||||
* but would be referenced in a TokenConfig in the if(matchedPattern) portion of getModelTokenValue.
|
||||
* So in order to preserve functionality for that case and any others which might reference an additional key I'm unaware of,
|
||||
* I've included it here until the interface can be typed more tightly.
|
||||
*/
|
||||
export interface TokenConfig {
|
||||
[key: string]: number;
|
||||
prompt: number;
|
||||
completion: number;
|
||||
context: number;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
/** An endpoint's config object mapping model keys to their respective prompt, completion rates, and context limit */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue