diff --git a/api/app/clients/specs/FakeClient.js b/api/app/clients/specs/FakeClient.js index d1d07a967d..8bd55bb999 100644 --- a/api/app/clients/specs/FakeClient.js +++ b/api/app/clients/specs/FakeClient.js @@ -1,4 +1,4 @@ -const { getModelMaxTokens } = require('@librechat/api'); +const { getModelMaxTokens } = require('librechat-data-provider'); const BaseClient = require('../BaseClient'); class FakeClient extends BaseClient { diff --git a/api/models/tx.js b/api/models/tx.js index 959c88e2b4..7f3bf67f0a 100644 --- a/api/models/tx.js +++ b/api/models/tx.js @@ -1,34 +1,24 @@ -const { matchModelName, findMatchingPattern } = require('@librechat/api'); +const { matchModelName, findMatchingPattern } = require('librechat-data-provider'); const defaultRate = 6; /** * Token Pricing Configuration * - * IMPORTANT: Key Ordering for Pattern Matching - * ============================================ - * The `findMatchingPattern` function iterates through object keys in REVERSE order - * (last-defined keys are checked first) and uses `modelName.includes(key)` for matching. + * Pattern Matching Strategy + * ======================== + * The `findMatchingPattern` function uses a longest-match strategy: it checks all keys + * and returns the longest key that is a substring of the model name. This ensures + * specific patterns always take priority over generic ones regardless of definition order. * - * This means: - * 1. BASE PATTERNS must be defined FIRST (e.g., "kimi", "moonshot") - * 2. SPECIFIC PATTERNS must be defined AFTER their base patterns (e.g., "kimi-k2", "kimi-k2.5") + * Example for Kimi models: + * kimi: { prompt: 0.6, completion: 2.5 }, // Base pattern (3 chars) + * 'kimi-k2': { prompt: 0.6, completion: 2.5 }, // More specific (7 chars) + * 'kimi-k2.5': { prompt: 0.6, completion: 3.0 }, // Most specific (9 chars) * - * Example ordering for Kimi models: - * kimi: { prompt: 0.6, completion: 2.5 }, // Base pattern - checked last - * 'kimi-k2': { prompt: 0.6, completion: 2.5 }, // More specific - checked before "kimi" - * 'kimi-k2.5': { prompt: 0.6, completion: 3.0 }, // Most specific - checked first + * For model name "kimi-k2.5", all three keys match, but "kimi-k2.5" wins (longest). * - * Why this matters: - * - Model name "kimi-k2.5" contains both "kimi" and "kimi-k2" as substrings - * - If "kimi" were checked first, it would incorrectly match and return wrong pricing - * - By defining specific patterns AFTER base patterns, they're checked first in reverse iteration - * - * This applies to BOTH `tokenValues` and `cacheTokenValues` objects. - * - * When adding new model families: - * 1. Define the base/generic pattern first - * 2. Define increasingly specific patterns after - * 3. Ensure no pattern is a substring of another that should match differently + * Keys are ordered base-to-specific for readability, but this is not required + * by the algorithm. This applies to BOTH `tokenValues` and `cacheTokenValues` objects. */ /** diff --git a/api/models/tx.spec.js b/api/models/tx.spec.js index df1bec8619..cc58df8a6e 100644 --- a/api/models/tx.spec.js +++ b/api/models/tx.spec.js @@ -1,6 +1,5 @@ /** Note: No hard-coded values should be used in this file. */ -const { maxTokensMap } = require('@librechat/api'); -const { EModelEndpoint } = require('librechat-data-provider'); +const { EModelEndpoint, maxTokensMap } = require('librechat-data-provider'); const { defaultRate, tokenValues, diff --git a/api/server/controllers/assistants/chatV1.js b/api/server/controllers/assistants/chatV1.js index 804594d0bf..f6244f0d48 100644 --- a/api/server/controllers/assistants/chatV1.js +++ b/api/server/controllers/assistants/chatV1.js @@ -1,7 +1,7 @@ const { v4 } = require('uuid'); const { sleep } = require('@librechat/agents'); const { logger } = require('@librechat/data-schemas'); -const { sendEvent, getBalanceConfig, getModelMaxTokens, countTokens } = require('@librechat/api'); +const { sendEvent, getBalanceConfig, countTokens } = require('@librechat/api'); const { Time, Constants, @@ -12,6 +12,7 @@ const { EModelEndpoint, ViolationTypes, ImageVisionTool, + getModelMaxTokens, checkOpenAIStorage, AssistantStreamEvents, } = require('librechat-data-provider'); diff --git a/api/server/controllers/assistants/chatV2.js b/api/server/controllers/assistants/chatV2.js index 414681d6dc..365a7ae3ce 100644 --- a/api/server/controllers/assistants/chatV2.js +++ b/api/server/controllers/assistants/chatV2.js @@ -1,7 +1,7 @@ const { v4 } = require('uuid'); const { sleep } = require('@librechat/agents'); const { logger } = require('@librechat/data-schemas'); -const { sendEvent, getBalanceConfig, getModelMaxTokens, countTokens } = require('@librechat/api'); +const { sendEvent, getBalanceConfig, countTokens } = require('@librechat/api'); const { Time, Constants, @@ -10,6 +10,7 @@ const { ContentTypes, ToolCallTypes, EModelEndpoint, + getModelMaxTokens, retrievalMimeTypes, AssistantStreamEvents, } = require('librechat-data-provider');