librechat-data-provider 0.8.504 → 0.8.506

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -392,6 +392,31 @@ const openAILikeProviders = new Set([
392
392
  const isOpenAILikeProvider = (provider) => {
393
393
  return openAILikeProviders.has(provider ?? "");
394
394
  };
395
+ /**
396
+ * Providers whose `usage_metadata.input_tokens` ALREADY INCLUDES cached tokens
397
+ * (`input_token_details.cache_*` is a subset, not an additional charge):
398
+ * Google/Vertex (`promptTokenCount`), OpenAI/Azure (`prompt_tokens`), and the
399
+ * OpenAI-compatible family. `@librechat/agents`' `getAnthropicUsageMetadata`
400
+ * folds `cache_creation` + `cache_read` into `input_tokens`, so Anthropic is a
401
+ * subset provider too; without this the cache portion is billed twice. Bedrock
402
+ * stays additive — its Converse path passes AWS `inputTokens` through unmodified.
403
+ * Single source of truth shared by the backend billing path
404
+ * (`packages/api/src/agents/usage.ts`) and the client usage normalization.
405
+ */
406
+ const cacheSubsetProviders = new Set([
407
+ "openAI",
408
+ "azureOpenAI",
409
+ "google",
410
+ "vertexai",
411
+ "xai",
412
+ "deepseek",
413
+ "openrouter",
414
+ "moonshot",
415
+ "anthropic"
416
+ ]);
417
+ const inputTokensIncludesCache = (provider) => {
418
+ return cacheSubsetProviders.has(provider ?? "");
419
+ };
395
420
  const isDocumentSupportedProvider = (provider) => {
396
421
  return documentSupportedProviders.has(provider ?? "");
397
422
  };
@@ -734,6 +759,7 @@ const anthropicSettings = {
734
759
  default: 1
735
760
  },
736
761
  promptCache: { default: true },
762
+ promptCacheTtl: { default: void 0 },
737
763
  thinking: { default: true },
738
764
  thinkingBudget: {
739
765
  min: 1024,
@@ -909,6 +935,8 @@ const tMessageSchema = zod.z.object({
909
935
  feedback: feedbackSchema.optional(),
910
936
  /** metadata */
911
937
  metadata: zod.z.record(zod.z.unknown()).optional(),
938
+ /** Output tokens for assistant messages, calibrated prompt-side estimate for user messages */
939
+ tokenCount: zod.z.number().optional(),
912
940
  contextMeta: zod.z.object({
913
941
  calibrationRatio: zod.z.number().optional().describe("EMA ratio of provider-reported vs local token estimates; seeds the pruner on subsequent runs"),
914
942
  encoding: zod.z.string().optional().describe("Tokenizer encoding used when this ratio was computed (e.g. \"claude\", \"o200k_base\")")
@@ -948,6 +976,7 @@ const tConversationSchema = zod.z.object({
948
976
  endpoint: eModelEndpointSchema.nullable(),
949
977
  endpointType: eModelEndpointSchema.nullable().optional(),
950
978
  isArchived: zod.z.boolean().optional(),
979
+ pinned: zod.z.boolean().optional(),
951
980
  title: zod.z.string().nullable().or(zod.z.literal("New Chat")).default("New Chat"),
952
981
  user: zod.z.string().optional(),
953
982
  messages: zod.z.array(zod.z.string()).optional(),
@@ -967,6 +996,7 @@ const tConversationSchema = zod.z.object({
967
996
  maxContextTokens: coerceNumber.optional(),
968
997
  max_tokens: coerceNumber.optional(),
969
998
  promptCache: zod.z.boolean().optional(),
999
+ promptCacheTtl: zod.z.enum(["5m", "1h"]).optional(),
970
1000
  system: zod.z.string().optional(),
971
1001
  thinking: zod.z.boolean().optional(),
972
1002
  thinkingBudget: coerceNumber.optional(),
@@ -1089,6 +1119,7 @@ const tQueryParamsSchema = tConversationSchema.pick({
1089
1119
  maxOutputTokens: true,
1090
1120
  /** @endpoints anthropic */
1091
1121
  promptCache: true,
1122
+ promptCacheTtl: true,
1092
1123
  thinking: true,
1093
1124
  thinkingBudget: true,
1094
1125
  thinkingLevel: true,
@@ -1331,7 +1362,10 @@ const openAIBaseSchema = tConversationSchema.pick({
1331
1362
  fileTokenLimit: true
1332
1363
  });
1333
1364
  const openAISchema = openAIBaseSchema.transform((obj) => removeNullishValues(obj, true)).catch(() => ({}));
1334
- const openRouterSchema = openAIBaseSchema.merge(tConversationSchema.pick({ promptCache: true })).transform((obj) => removeNullishValues(obj, true)).catch(() => ({}));
1365
+ const openRouterSchema = openAIBaseSchema.merge(tConversationSchema.pick({
1366
+ promptCache: true,
1367
+ promptCacheTtl: true
1368
+ })).transform((obj) => removeNullishValues(obj, true)).catch(() => ({}));
1335
1369
  const compactGoogleSchema = googleBaseSchema.transform((obj) => {
1336
1370
  const newObj = { ...obj };
1337
1371
  if (newObj.temperature === google.temperature.default) delete newObj.temperature;
@@ -1351,6 +1385,7 @@ const anthropicBaseSchema = tConversationSchema.pick({
1351
1385
  topK: true,
1352
1386
  resendFiles: true,
1353
1387
  promptCache: true,
1388
+ promptCacheTtl: true,
1354
1389
  thinking: true,
1355
1390
  thinkingBudget: true,
1356
1391
  effort: true,
@@ -1767,6 +1802,7 @@ const tModelSpecSchema = zod.z.object({
1767
1802
  showIconInMenu: zod.z.boolean().optional(),
1768
1803
  showIconInHeader: zod.z.boolean().optional(),
1769
1804
  showOnLanding: zod.z.boolean().optional(),
1805
+ conversation_starters: zod.z.array(zod.z.string()).optional(),
1770
1806
  iconURL: zod.z.union([zod.z.string(), eModelEndpointSchema]).optional(),
1771
1807
  authType: authTypeSchema.optional(),
1772
1808
  hideBadgeRow: zod.z.boolean().optional(),
@@ -1876,6 +1912,7 @@ const fullMimeTypesList = [
1876
1912
  "application/vnd.coffeescript",
1877
1913
  "application/xml",
1878
1914
  "application/zip",
1915
+ "application/x-zip-compressed",
1879
1916
  "application/x-parquet",
1880
1917
  "application/vnd.oasis.opendocument.text",
1881
1918
  "application/vnd.oasis.opendocument.spreadsheet",
@@ -1933,6 +1970,7 @@ const codeInterpreterMimeTypesList = [
1933
1970
  "application/typescript",
1934
1971
  "application/xml",
1935
1972
  "application/zip",
1973
+ "application/x-zip-compressed",
1936
1974
  "application/x-parquet",
1937
1975
  ...excelFileTypes
1938
1976
  ];
@@ -1972,7 +2010,7 @@ const isBedrockDocumentType = (mimeType) => mimeType != null && mimeType in bedr
1972
2010
  const bedrockDocumentExtensions = ".pdf,.csv,.doc,.docx,.xls,.xlsx,.html,.htm,.txt,.md,application/pdf,text/csv,application/csv,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,text/html,text/plain,text/markdown";
1973
2011
  const excelMimeTypes = /^application\/(vnd\.ms-excel|msexcel|x-msexcel|x-ms-excel|x-excel|x-dos_ms_excel|xls|x-xls|vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet)$/;
1974
2012
  const textMimeTypes = /^(text\/(x-c|x-csharp|tab-separated-values|x-c\+\+|x-h|x-java|html|markdown|x-php|x-python|x-script\.python|x-ruby|x-tex|plain|css|vtt|javascript|csv|xml|calendar))$/;
1975
- const applicationMimeTypes = /^(application\/(epub\+zip|csv|json|msword|pdf|x-tar|x-sh|typescript|sql|yaml|x-parquet|vnd\.apache\.parquet|vnd\.coffeescript|vnd\.openxmlformats-officedocument\.(wordprocessingml\.document|presentationml\.presentation|spreadsheetml\.sheet)|vnd\.oasis\.opendocument\.(text|spreadsheet|presentation|graphics)|xml|zip))$/;
2013
+ const applicationMimeTypes = /^(application\/(epub\+zip|csv|json|msword|pdf|x-tar|x-sh|x-zip-compressed|typescript|sql|yaml|x-parquet|vnd\.apache\.parquet|vnd\.coffeescript|vnd\.openxmlformats-officedocument\.(wordprocessingml\.document|presentationml\.presentation|spreadsheetml\.sheet)|vnd\.oasis\.opendocument\.(text|spreadsheet|presentation|graphics)|xml|zip))$/;
1976
2014
  const imageMimeTypes = /^image\/(jpeg|gif|png|webp|heic|heif)$/;
1977
2015
  const audioMimeTypes = /^audio\/(mp3|mpeg|mpeg3|wav|wave|x-wav|ogg|vorbis|mp4|m4a|x-m4a|flac|x-flac|webm|aac|wma|opus)$/;
1978
2016
  const videoMimeTypes = /^video\/(mp4|avi|mov|wmv|flv|webm|mkv|m4v|3gp|ogv)$/;
@@ -2140,6 +2178,7 @@ const imageTypeMapping = {
2140
2178
  };
2141
2179
  /** Normalizes non-standard MIME types that browsers may report to their canonical forms */
2142
2180
  const mimeTypeAliases = {
2181
+ "application/x-zip-compressed": "application/zip",
2143
2182
  "text/x-python-script": "text/x-python",
2144
2183
  "text/x-markdown": "text/markdown"
2145
2184
  };
@@ -2438,6 +2477,7 @@ const conversationById = (id) => `${conversationsRoot}/${id}`;
2438
2477
  const genTitle$1 = (conversationId) => `${conversationsRoot}/gen_title/${encodeURIComponent(conversationId)}`;
2439
2478
  const updateConversation$1 = () => `${conversationsRoot}/update`;
2440
2479
  const archiveConversation$1 = () => `${conversationsRoot}/archive`;
2480
+ const pinConversation$1 = () => `${conversationsRoot}/pin`;
2441
2481
  const deleteConversation$1 = () => `${conversationsRoot}`;
2442
2482
  const deleteAllConversation = () => `${conversationsRoot}/all`;
2443
2483
  const importConversation = () => `${conversationsRoot}/import`;
@@ -2453,6 +2493,8 @@ const searchEnabled = () => `${BASE_URL}/api/search/enable`;
2453
2493
  const presets = () => `${BASE_URL}/api/presets`;
2454
2494
  const deletePreset$1 = () => `${BASE_URL}/api/presets/delete`;
2455
2495
  const aiEndpoints = () => `${BASE_URL}/api/endpoints`;
2496
+ const tokenConfig = () => `${BASE_URL}/api/endpoints/token-config`;
2497
+ const contextProjection = () => `${BASE_URL}/api/endpoints/context-projection`;
2456
2498
  const models = () => `${BASE_URL}/api/models`;
2457
2499
  const tokenizer = () => `${BASE_URL}/api/tokenizer`;
2458
2500
  const login$1 = () => `${BASE_URL}/api/auth/login`;
@@ -3360,6 +3402,15 @@ const defaultAssistantsVersion = {
3360
3402
  const baseEndpointSchema = zod.z.object({
3361
3403
  streamRate: zod.z.number().optional(),
3362
3404
  baseURL: zod.z.string().optional(),
3405
+ /**
3406
+ * Custom request headers forwarded to the provider on every request. Values
3407
+ * support the same placeholder resolution as custom endpoints — env vars
3408
+ * (`${VAR}`), user fields (`{{LIBRECHAT_USER_*}}`), and request-body fields
3409
+ * (`{{LIBRECHAT_BODY_CONVERSATIONID}}`). Primarily for routing built-in
3410
+ * providers through an AI gateway / reverse proxy that consumes metadata
3411
+ * headers (provider-native request shaping is preserved).
3412
+ */
3413
+ headers: zod.z.record(zod.z.string()).optional(),
3363
3414
  titlePrompt: zod.z.string().optional(),
3364
3415
  titleModel: zod.z.string().optional(),
3365
3416
  titleConvo: zod.z.boolean().optional(),
@@ -3556,6 +3607,14 @@ const endpointSchema = baseEndpointSchema.merge(zod.z.object({
3556
3607
  }),
3557
3608
  iconURL: zod.z.string().optional(),
3558
3609
  modelDisplayLabel: zod.z.string().optional(),
3610
+ /**
3611
+ * Forces the endpoint to use a provider's native client / request format
3612
+ * instead of the default OpenAI-compatible client. Currently supports
3613
+ * `anthropic`, for endpoints that speak the Anthropic `/v1/messages` API
3614
+ * (Anthropic itself or Anthropic-compatible gateways). Omit for
3615
+ * OpenAI-compatible endpoints.
3616
+ */
3617
+ provider: zod.z.literal("anthropic").optional(),
3559
3618
  headers: zod.z.record(zod.z.string()).optional(),
3560
3619
  addParams: addParamsSchema.optional(),
3561
3620
  dropParams: zod.z.array(zod.z.string()).optional(),
@@ -3570,7 +3629,15 @@ const endpointSchema = baseEndpointSchema.merge(zod.z.object({
3570
3629
  "system",
3571
3630
  "user",
3572
3631
  "assistant"
3573
- ]).optional()
3632
+ ]).optional(),
3633
+ /** Static per-model token config: context window and per-million-token rates */
3634
+ tokenConfig: zod.z.record(zod.z.object({
3635
+ prompt: zod.z.number(),
3636
+ completion: zod.z.number(),
3637
+ context: zod.z.number(),
3638
+ cacheRead: zod.z.number().optional(),
3639
+ cacheWrite: zod.z.number().optional()
3640
+ })).optional()
3574
3641
  }));
3575
3642
  const azureEndpointSchema = zod.z.object({
3576
3643
  groups: azureGroupConfigsSchema,
@@ -3797,6 +3864,12 @@ const interfaceSchema = zod.z.object({
3797
3864
  retainAgentFiles: zod.z.boolean().optional(),
3798
3865
  runCode: zod.z.boolean().optional(),
3799
3866
  webSearch: zod.z.boolean().optional(),
3867
+ contextUsage: zod.z.boolean().optional(),
3868
+ contextCost: zod.z.boolean().optional(),
3869
+ currency: zod.z.object({
3870
+ code: zod.z.string(),
3871
+ rate: zod.z.number().positive()
3872
+ }).optional(),
3800
3873
  peoplePicker: zod.z.object({
3801
3874
  users: zod.z.boolean().optional(),
3802
3875
  groups: zod.z.boolean().optional(),
@@ -3847,6 +3920,8 @@ const interfaceSchema = zod.z.object({
3847
3920
  autoSubmitFromUrl: true,
3848
3921
  runCode: true,
3849
3922
  webSearch: true,
3923
+ contextUsage: true,
3924
+ contextCost: false,
3850
3925
  peoplePicker: {
3851
3926
  users: true,
3852
3927
  groups: true,
@@ -4830,7 +4905,7 @@ let TTSProviders = /* @__PURE__ */ function(TTSProviders) {
4830
4905
  /** Enum for app-wide constants */
4831
4906
  let Constants = /* @__PURE__ */ function(Constants) {
4832
4907
  /**
4833
- * Key for the app's version. The placeholder `v0.8.6` is
4908
+ * Key for the app's version. The placeholder `v0.8.7-rc1` is
4834
4909
  * swapped in by `@rollup/plugin-replace` during `npm run build:data-provider`
4835
4910
  * using the value of the root `package.json`'s `version` field. Consumers
4836
4911
  * always import this via the built dist bundle (see `main` field in
@@ -4838,9 +4913,9 @@ let Constants = /* @__PURE__ */ function(Constants) {
4838
4913
  * substituted value. Only tests that import the TypeScript source directly
4839
4914
  * would observe the raw placeholder.
4840
4915
  */
4841
- Constants["VERSION"] = "v0.8.6";
4916
+ Constants["VERSION"] = "v0.8.7-rc1";
4842
4917
  /** Key for the Custom Config's version (librechat.yaml). */
4843
- Constants["CONFIG_VERSION"] = "1.3.12";
4918
+ Constants["CONFIG_VERSION"] = "1.3.13";
4844
4919
  /** Standard value for the first message's `parentMessageId` value, to indicate no parent exists. */
4845
4920
  Constants["NO_PARENT"] = "00000000-0000-0000-0000-000000000000";
4846
4921
  /** Standard value to use whatever the submission prelim. `responseMessageId` is */
@@ -5267,6 +5342,8 @@ let QueryKeys = /* @__PURE__ */ function(QueryKeys) {
5267
5342
  QueryKeys["models"] = "models";
5268
5343
  QueryKeys["balance"] = "balance";
5269
5344
  QueryKeys["endpoints"] = "endpoints";
5345
+ QueryKeys["tokenConfig"] = "tokenConfig";
5346
+ QueryKeys["contextProjection"] = "contextProjection";
5270
5347
  QueryKeys["presets"] = "presets";
5271
5348
  QueryKeys["searchResults"] = "searchResults";
5272
5349
  QueryKeys["tokenCount"] = "tokenCount";
@@ -5365,6 +5442,7 @@ let MutationKeys = /* @__PURE__ */ function(MutationKeys) {
5365
5442
  MutationKeys["updateSkillNode"] = "updateSkillNode";
5366
5443
  MutationKeys["deleteSkillNode"] = "deleteSkillNode";
5367
5444
  MutationKeys["updateSkillNodeContent"] = "updateSkillNodeContent";
5445
+ MutationKeys["convoPin"] = "convoPin";
5368
5446
  return MutationKeys;
5369
5447
  }({});
5370
5448
  //#endregion
@@ -5647,6 +5725,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5647
5725
  getBanner: () => getBanner,
5648
5726
  getCategories: () => getCategories,
5649
5727
  getCodeOutputDownload: () => getCodeOutputDownload,
5728
+ getContextProjection: () => getContextProjection,
5650
5729
  getConversationById: () => getConversationById,
5651
5730
  getConversationTags: () => getConversationTags,
5652
5731
  getConversations: () => getConversations,
@@ -5692,6 +5771,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5692
5771
  getSkillStates: () => getSkillStates,
5693
5772
  getSkillTree: () => getSkillTree,
5694
5773
  getStartupConfig: () => getStartupConfig,
5774
+ getTokenConfig: () => getTokenConfig,
5695
5775
  getToolCalls: () => getToolCalls,
5696
5776
  getUser: () => getUser,
5697
5777
  getUserBalance: () => getUserBalance,
@@ -5713,6 +5793,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5713
5793
  login: () => login,
5714
5794
  logout: () => logout,
5715
5795
  makePromptProduction: () => makePromptProduction,
5796
+ pinConversation: () => pinConversation,
5716
5797
  rebuildConversationTags: () => rebuildConversationTags,
5717
5798
  recordPromptGroupUsage: () => recordPromptGroupUsage,
5718
5799
  regenerateBackupCodes: () => regenerateBackupCodes,
@@ -5923,6 +6004,12 @@ const getStartupConfig = (options) => {
5923
6004
  const getAIEndpoints = () => {
5924
6005
  return request_default.get(aiEndpoints());
5925
6006
  };
6007
+ const getTokenConfig = () => {
6008
+ return request_default.get(tokenConfig());
6009
+ };
6010
+ const getContextProjection = (payload) => {
6011
+ return request_default.post(contextProjection(), payload);
6012
+ };
5926
6013
  const getModels = async () => {
5927
6014
  return request_default.get(models());
5928
6015
  };
@@ -6221,6 +6308,9 @@ function assignConversationToProject(payload) {
6221
6308
  const { conversationId, projectId } = payload;
6222
6309
  return request_default.put(projectConversation(conversationId), { projectId });
6223
6310
  }
6311
+ function pinConversation(payload) {
6312
+ return request_default.post(pinConversation$1(), { arg: payload });
6313
+ }
6224
6314
  function genTitle(payload) {
6225
6315
  return request_default.get(genTitle$1(payload.conversationId));
6226
6316
  }
@@ -7290,6 +7380,12 @@ Object.defineProperty(exports, "buildLoginRedirectUrl", {
7290
7380
  return buildLoginRedirectUrl;
7291
7381
  }
7292
7382
  });
7383
+ Object.defineProperty(exports, "cacheSubsetProviders", {
7384
+ enumerable: true,
7385
+ get: function() {
7386
+ return cacheSubsetProviders;
7387
+ }
7388
+ });
7293
7389
  Object.defineProperty(exports, "cancelMCPOAuth", {
7294
7390
  enumerable: true,
7295
7391
  get: function() {
@@ -7926,6 +8022,12 @@ Object.defineProperty(exports, "initialModelsConfig", {
7926
8022
  return initialModelsConfig;
7927
8023
  }
7928
8024
  });
8025
+ Object.defineProperty(exports, "inputTokensIncludesCache", {
8026
+ enumerable: true,
8027
+ get: function() {
8028
+ return inputTokensIncludesCache;
8029
+ }
8030
+ });
7929
8031
  Object.defineProperty(exports, "interfaceSchema", {
7930
8032
  enumerable: true,
7931
8033
  get: function() {
@@ -8515,4 +8617,4 @@ Object.defineProperty(exports, "webSearchSchema", {
8515
8617
  }
8516
8618
  });
8517
8619
 
8518
- //# sourceMappingURL=data-service-Dk-uLruo.js.map
8620
+ //# sourceMappingURL=data-service-CCdWvcRd.js.map