librechat-data-provider 0.8.508 → 0.8.521

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.
Files changed (42) hide show
  1. package/dist/{data-service-DN-HeTC-.js → data-service-DOIF4BkW.js} +1211 -92
  2. package/dist/data-service-DOIF4BkW.js.map +1 -0
  3. package/dist/{data-service-DgNwjhBS.mjs → data-service-pwrlWjJs.mjs} +1062 -93
  4. package/dist/data-service-pwrlWjJs.mjs.map +1 -0
  5. package/dist/index.js +472 -57
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +440 -58
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/react-query/index.js +1 -1
  10. package/dist/react-query/index.js.map +1 -1
  11. package/dist/react-query/index.mjs +1 -1
  12. package/dist/react-query/index.mjs.map +1 -1
  13. package/dist/types/actions.d.ts +1 -1
  14. package/dist/types/api-endpoints.d.ts +11 -2
  15. package/dist/types/bedrock.d.ts +57 -0
  16. package/dist/types/config.d.ts +4230 -183
  17. package/dist/types/data-service.d.ts +28 -14
  18. package/dist/types/feedback.d.ts +9 -1
  19. package/dist/types/file-config.d.ts +41 -5
  20. package/dist/types/generate.d.ts +8 -0
  21. package/dist/types/keys.d.ts +7 -2
  22. package/dist/types/mcp.d.ts +45 -24
  23. package/dist/types/messages.d.ts +8 -0
  24. package/dist/types/models.d.ts +120 -0
  25. package/dist/types/parameterSettings.d.ts +2 -2
  26. package/dist/types/parsers.d.ts +3 -1
  27. package/dist/types/react-query/react-query-service.d.ts +2 -7
  28. package/dist/types/request.d.ts +3 -1
  29. package/dist/types/schemas.d.ts +211 -11
  30. package/dist/types/types/agents.d.ts +211 -1
  31. package/dist/types/types/assistants.d.ts +77 -5
  32. package/dist/types/types/files.d.ts +18 -7
  33. package/dist/types/types/mcpServers.d.ts +25 -0
  34. package/dist/types/types/mutations.d.ts +1 -0
  35. package/dist/types/types/queries.d.ts +17 -3
  36. package/dist/types/types/runs.d.ts +114 -25
  37. package/dist/types/types/skills.d.ts +25 -6
  38. package/dist/types/types.d.ts +117 -2
  39. package/dist/types/upload.d.ts +2 -0
  40. package/package.json +4 -4
  41. package/dist/data-service-DN-HeTC-.js.map +0 -1
  42. package/dist/data-service-DgNwjhBS.mjs.map +0 -1
@@ -189,6 +189,9 @@ const feedbackSchema = zod.z.object({
189
189
  rating: feedbackRatingSchema,
190
190
  tag: feedbackTagKeySchema,
191
191
  text: zod.z.string().max(1024).optional()
192
+ }).refine(({ rating, tag }) => FEEDBACK_TAGS.some((feedbackTag) => feedbackTag.key === tag && feedbackTag.direction === rating), {
193
+ message: "Feedback tag does not match rating",
194
+ path: ["tag"]
192
195
  });
193
196
  function toMinimalFeedback(feedback) {
194
197
  if (!feedback?.rating || !feedback?.tag || !feedback.tag.key) return;
@@ -484,6 +487,7 @@ let ReasoningEffort = /* @__PURE__ */ function(ReasoningEffort) {
484
487
  ReasoningEffort["medium"] = "medium";
485
488
  ReasoningEffort["high"] = "high";
486
489
  ReasoningEffort["xhigh"] = "xhigh";
490
+ ReasoningEffort["max"] = "max";
487
491
  return ReasoningEffort;
488
492
  }({});
489
493
  let ReasoningParameterFormat = /* @__PURE__ */ function(ReasoningParameterFormat) {
@@ -550,6 +554,21 @@ let ThinkingLevel = /* @__PURE__ */ function(ThinkingLevel) {
550
554
  ThinkingLevel["high"] = "high";
551
555
  return ThinkingLevel;
552
556
  }({});
557
+ /** OpenAI Responses API `reasoning.mode` (GPT-5.6+). */
558
+ let ReasoningMode = /* @__PURE__ */ function(ReasoningMode) {
559
+ ReasoningMode["unset"] = "";
560
+ ReasoningMode["standard"] = "standard";
561
+ ReasoningMode["pro"] = "pro";
562
+ return ReasoningMode;
563
+ }({});
564
+ /** OpenAI Responses API `reasoning.context` (GPT-5.6+). */
565
+ let ReasoningContext = /* @__PURE__ */ function(ReasoningContext) {
566
+ ReasoningContext["unset"] = "";
567
+ ReasoningContext["auto"] = "auto";
568
+ ReasoningContext["current_turn"] = "current_turn";
569
+ ReasoningContext["all_turns"] = "all_turns";
570
+ return ReasoningContext;
571
+ }({});
553
572
  const imageDetailNumeric = {
554
573
  ["low"]: 0,
555
574
  ["auto"]: 1,
@@ -569,6 +588,8 @@ const eThinkingDisplaySchema = zod.z.nativeEnum(ThinkingDisplay);
569
588
  const eReasoningSummarySchema = zod.z.nativeEnum(ReasoningSummary);
570
589
  const eVerbositySchema = zod.z.nativeEnum(Verbosity);
571
590
  const eThinkingLevelSchema = zod.z.nativeEnum(ThinkingLevel);
591
+ const eReasoningModeSchema = zod.z.nativeEnum(ReasoningMode);
592
+ const eReasoningContextSchema = zod.z.nativeEnum(ReasoningContext);
572
593
  const defaultAssistantFormValues = {
573
594
  assistant: "",
574
595
  id: "",
@@ -600,6 +621,7 @@ const defaultAgentFormValues = {
600
621
  ["execute_code"]: false,
601
622
  ["file_search"]: false,
602
623
  ["web_search"]: false,
624
+ ["memory"]: false,
603
625
  category: "general",
604
626
  support_contact: {
605
627
  name: "",
@@ -612,7 +634,9 @@ const defaultAgentFormValues = {
612
634
  * (full catalog unless `skills` narrows it). Anything else = inactive. */
613
635
  skills_enabled: void 0,
614
636
  /** `undefined` = feature disabled by default (no subagent tool injected). */
615
- subagents: void 0
637
+ subagents: void 0,
638
+ /** Memory partition: 'agent' isolates memories per (user, agent); default shared pool */
639
+ memory_scope: void 0
616
640
  };
617
641
  const ImageVisionTool = {
618
642
  type: "function",
@@ -732,6 +756,7 @@ const CLAUDE_4_64K_MAX_OUTPUT = 64e3;
732
756
  const CLAUDE_32K_MAX_OUTPUT = 32e3;
733
757
  const DEFAULT_MAX_OUTPUT = 8192;
734
758
  const LEGACY_ANTHROPIC_MAX_OUTPUT = 4096;
759
+ const CLAUDE_SONNET_128K_OUTPUT_PATTERN = /claude-sonnet[-.]?(?:4[-.]?(?:[6-9]|\d{2})|[5-9]|\d{2,})(?=$|[^0-9])/;
735
760
  /**
736
761
  * Claude "Mythos-class" model families — new top-level classes (peers of
737
762
  * `opus`/`sonnet`/`haiku`) that ship with the post-Opus-4.7 modern profile:
@@ -775,6 +800,7 @@ const anthropicSettings = {
775
800
  reset: (modelName) => {
776
801
  if (isMythosClassModel(modelName)) return ANTHROPIC_MAX_OUTPUT;
777
802
  if (/claude-opus[-.]?(?:4[-.]?(?:[6-9]|\d{2,})|[5-9]|\d{2,})/.test(modelName)) return ANTHROPIC_MAX_OUTPUT;
803
+ if (CLAUDE_SONNET_128K_OUTPUT_PATTERN.test(modelName)) return ANTHROPIC_MAX_OUTPUT;
778
804
  if (/claude-(?:sonnet|haiku)[-.]?[4-9]/.test(modelName)) return CLAUDE_4_64K_MAX_OUTPUT;
779
805
  if (/claude-opus[-.]?(?:[5-9]|4[-.]?([5-9]|\d{2,}))/.test(modelName)) return CLAUDE_4_64K_MAX_OUTPUT;
780
806
  if (/claude-opus[-.]?[4-9]/.test(modelName)) return CLAUDE_32K_MAX_OUTPUT;
@@ -789,6 +815,10 @@ const anthropicSettings = {
789
815
  if (value > ANTHROPIC_MAX_OUTPUT) return ANTHROPIC_MAX_OUTPUT;
790
816
  return value;
791
817
  }
818
+ if (CLAUDE_SONNET_128K_OUTPUT_PATTERN.test(modelName)) {
819
+ if (value > ANTHROPIC_MAX_OUTPUT) return ANTHROPIC_MAX_OUTPUT;
820
+ return value;
821
+ }
792
822
  if (/claude-(?:sonnet|haiku)[-.]?[4-9]/.test(modelName) && value > CLAUDE_4_64K_MAX_OUTPUT) return CLAUDE_4_64K_MAX_OUTPUT;
793
823
  if (/claude-opus[-.]?(?:[5-9]|4[-.]?([5-9]|\d{2,}))/.test(modelName)) {
794
824
  if (value > CLAUDE_4_64K_MAX_OUTPUT) return CLAUDE_4_64K_MAX_OUTPUT;
@@ -967,6 +997,16 @@ const tMessageSchema = zod.z.object({
967
997
  */
968
998
  quotes: zod.z.array(zod.z.string()).optional()
969
999
  });
1000
+ /**
1001
+ * Which memory partition an agent reads/writes.
1002
+ * `user` = the shared personal pool (default); `agent` = a partition
1003
+ * isolated per (user, agent) so the agent only sees its own memories.
1004
+ */
1005
+ let MemoryScope = /* @__PURE__ */ function(MemoryScope) {
1006
+ MemoryScope["user"] = "user";
1007
+ MemoryScope["agent"] = "agent";
1008
+ return MemoryScope;
1009
+ }({});
970
1010
  const coerceNumber = zod.z.union([zod.z.number(), zod.z.string()]).transform((val) => {
971
1011
  if (typeof val === "string") return val.trim() === "" ? void 0 : parseFloat(val);
972
1012
  return val;
@@ -985,6 +1025,8 @@ const tConversationSchema = zod.z.object({
985
1025
  endpointType: eModelEndpointSchema.nullable().optional(),
986
1026
  isArchived: zod.z.boolean().optional(),
987
1027
  pinned: zod.z.boolean().optional(),
1028
+ /** Server-derived: an active shared link exists for this conversation. Not persisted. */
1029
+ isShared: zod.z.boolean().optional(),
988
1030
  title: zod.z.string().nullable().or(zod.z.literal("New Chat")).default("New Chat"),
989
1031
  user: zod.z.string().optional(),
990
1032
  messages: zod.z.array(zod.z.string()).optional(),
@@ -1022,11 +1064,14 @@ const tConversationSchema = zod.z.object({
1022
1064
  imageDetail: eImageDetailSchema.optional(),
1023
1065
  reasoning_effort: eReasoningEffortSchema.optional().nullable(),
1024
1066
  reasoning_summary: eReasoningSummarySchema.optional().nullable(),
1067
+ reasoning_mode: eReasoningModeSchema.optional().nullable(),
1068
+ reasoning_context: eReasoningContextSchema.optional().nullable(),
1025
1069
  verbosity: eVerbositySchema.optional().nullable(),
1026
1070
  useResponsesApi: zod.z.boolean().optional(),
1027
1071
  effort: eAnthropicEffortSchema.optional().nullable(),
1028
1072
  thinkingDisplay: eThinkingDisplaySchema.optional().nullable(),
1029
1073
  web_search: zod.z.boolean().optional(),
1074
+ url_context: zod.z.boolean().optional(),
1030
1075
  disableStreaming: zod.z.boolean().optional(),
1031
1076
  assistant_id: zod.z.string().optional(),
1032
1077
  agent_id: zod.z.string().optional(),
@@ -1112,11 +1157,17 @@ const tQueryParamsSchema = tConversationSchema.pick({
1112
1157
  /** @endpoints openAI, custom, azureOpenAI */
1113
1158
  reasoning_summary: true,
1114
1159
  /** @endpoints openAI, custom, azureOpenAI */
1160
+ reasoning_mode: true,
1161
+ /** @endpoints openAI, custom, azureOpenAI */
1162
+ reasoning_context: true,
1163
+ /** @endpoints openAI, custom, azureOpenAI */
1115
1164
  verbosity: true,
1116
1165
  /** @endpoints openAI, custom, azureOpenAI */
1117
1166
  useResponsesApi: true,
1118
1167
  /** @endpoints openAI, anthropic, google */
1119
1168
  web_search: true,
1169
+ /** @endpoints google */
1170
+ url_context: true,
1120
1171
  /** @endpoints openAI, custom, azureOpenAI */
1121
1172
  disableStreaming: true,
1122
1173
  /** @endpoints google, anthropic, bedrock */
@@ -1214,6 +1265,7 @@ const googleBaseSchema = tConversationSchema.pick({
1214
1265
  thinkingBudget: true,
1215
1266
  thinkingLevel: true,
1216
1267
  web_search: true,
1268
+ url_context: true,
1217
1269
  fileTokenLimit: true,
1218
1270
  iconURL: true,
1219
1271
  greeting: true,
@@ -1240,7 +1292,8 @@ const googleGenConfigSchema = zod.z.object({
1240
1292
  thinkingBudget: coerceNumber.optional(),
1241
1293
  thinkingLevel: zod.z.string().optional()
1242
1294
  }).optional(),
1243
- web_search: zod.z.boolean().optional()
1295
+ web_search: zod.z.boolean().optional(),
1296
+ url_context: zod.z.boolean().optional()
1244
1297
  }).strip().optional();
1245
1298
  function removeNullishValues(obj, removeEmptyStrings) {
1246
1299
  const newObj = { ...obj };
@@ -1363,6 +1416,8 @@ const openAIBaseSchema = tConversationSchema.pick({
1363
1416
  max_tokens: true,
1364
1417
  reasoning_effort: true,
1365
1418
  reasoning_summary: true,
1419
+ reasoning_mode: true,
1420
+ reasoning_context: true,
1366
1421
  verbosity: true,
1367
1422
  useResponsesApi: true,
1368
1423
  web_search: true,
@@ -1811,12 +1866,17 @@ const tModelSpecSchema = zod.z.object({
1811
1866
  showIconInHeader: zod.z.boolean().optional(),
1812
1867
  showOnLanding: zod.z.boolean().optional(),
1813
1868
  conversation_starters: zod.z.array(zod.z.string()).optional(),
1869
+ showInMenu: zod.z.boolean().optional(),
1814
1870
  iconURL: zod.z.union([zod.z.string(), eModelEndpointSchema]).optional(),
1815
1871
  authType: authTypeSchema.optional(),
1816
1872
  hideBadgeRow: zod.z.boolean().optional(),
1817
1873
  webSearch: zod.z.boolean().optional(),
1818
1874
  fileSearch: zod.z.boolean().optional(),
1819
1875
  executeCode: zod.z.boolean().optional(),
1876
+ memory: zod.z.boolean().optional(),
1877
+ askUserQuestion: zod.z.boolean().optional(),
1878
+ runInBackground: zod.z.union([zod.z.boolean(), zod.z.array(zod.z.string())]).optional(),
1879
+ describeIntent: zod.z.union([zod.z.boolean(), zod.z.array(zod.z.string())]).optional(),
1820
1880
  artifacts: zod.z.union([zod.z.string(), zod.z.boolean()]).optional(),
1821
1881
  mcpServers: zod.z.array(zod.z.string()).optional(),
1822
1882
  skills: zod.z.union([zod.z.boolean(), zod.z.array(zod.z.string())]).optional(),
@@ -1898,6 +1958,7 @@ const fullMimeTypesList = [
1898
1958
  "application/pdf",
1899
1959
  "text/x-php",
1900
1960
  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
1961
+ "application/vnd.openxmlformats-officedocument.presentationml.template",
1901
1962
  "text/x-python",
1902
1963
  "text/x-script.python",
1903
1964
  "text/x-ruby",
@@ -1928,6 +1989,7 @@ const fullMimeTypesList = [
1928
1989
  "application/vnd.oasis.opendocument.graphics",
1929
1990
  "image/svg",
1930
1991
  "image/svg+xml",
1992
+ "message/rfc822",
1931
1993
  "video/mp4",
1932
1994
  "video/avi",
1933
1995
  "video/mov",
@@ -1961,6 +2023,7 @@ const codeInterpreterMimeTypesList = [
1961
2023
  "application/pdf",
1962
2024
  "text/x-php",
1963
2025
  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
2026
+ "application/vnd.openxmlformats-officedocument.presentationml.template",
1964
2027
  "text/x-python",
1965
2028
  "text/x-script.python",
1966
2029
  "text/x-ruby",
@@ -1993,6 +2056,7 @@ const retrievalMimeTypesList = [
1993
2056
  "application/pdf",
1994
2057
  "text/x-php",
1995
2058
  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
2059
+ "application/vnd.openxmlformats-officedocument.presentationml.template",
1996
2060
  "text/x-python",
1997
2061
  "text/x-script.python",
1998
2062
  "text/x-ruby",
@@ -2014,11 +2078,34 @@ const bedrockDocumentFormats = {
2014
2078
  "text/markdown": "md"
2015
2079
  };
2016
2080
  const isBedrockDocumentType = (mimeType) => mimeType != null && mimeType in bedrockDocumentFormats;
2081
+ /** MIME types Bedrock's Converse document path can send to the model (mirrors `bedrockDocumentFormats`). */
2082
+ const bedrockDocumentMimeTypes = Object.keys(bedrockDocumentFormats);
2017
2083
  /** File extensions accepted by Bedrock document uploads (for input accept attributes) */
2018
2084
  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";
2085
+ /** Textual `application/*` MIME types that can be decoded and sent as plain text */
2086
+ const textualApplicationTypes = new Set([
2087
+ "application/json",
2088
+ "application/xml",
2089
+ "application/yaml",
2090
+ "application/sql",
2091
+ "application/typescript",
2092
+ "application/x-sh",
2093
+ "application/csv"
2094
+ ]);
2095
+ /**
2096
+ * MIME types the Anthropic Messages API accepts as a plain-text document source
2097
+ * (`source.type: 'text'`)
2098
+ */
2099
+ const isAnthropicTextDocumentType = (mimeType) => mimeType != null && (mimeType.startsWith("text/") || textualApplicationTypes.has(mimeType));
2100
+ /**
2101
+ * MIME types the Anthropic Messages API document path can send to the model
2102
+ * (mirrors `isBedrockDocumentType`): PDF via base64, textual types via a
2103
+ * plain-text document source. All other types are rejected with a provider 400.
2104
+ */
2105
+ const isAnthropicDocumentType = (mimeType) => mimeType === "application/pdf" || isAnthropicTextDocumentType(mimeType);
2019
2106
  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)$/;
2020
2107
  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))$/;
2021
- 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))$/;
2108
+ 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|template)|spreadsheetml\.sheet)|vnd\.oasis\.opendocument\.(text|spreadsheet|presentation|graphics)|xml|zip))$/;
2022
2109
  const imageMimeTypes = /^image\/(jpeg|gif|png|webp|heic|heif)$/;
2023
2110
  const audioMimeTypes = /^audio\/(mp3|mpeg|mpeg3|wav|wave|x-wav|ogg|vorbis|mp4|m4a|x-m4a|flac|x-flac|webm|aac|wma|opus)$/;
2024
2111
  const videoMimeTypes = /^video\/(mp4|avi|mov|wmv|flv|webm|mkv|m4v|3gp|ogv)$/;
@@ -2027,6 +2114,7 @@ const defaultOCRMimeTypes = [
2027
2114
  excelMimeTypes,
2028
2115
  /^application\/pdf$/,
2029
2116
  /^application\/vnd\.openxmlformats-officedocument\.(wordprocessingml\.document|presentationml\.presentation)$/,
2117
+ /^application\/vnd\.openxmlformats-officedocument\.presentationml\.template$/,
2030
2118
  /^application\/vnd\.ms-(word|powerpoint)$/,
2031
2119
  /^application\/epub\+zip$/,
2032
2120
  /^application\/vnd\.oasis\.opendocument\.(text|spreadsheet|presentation|graphics)$/
@@ -2048,7 +2136,8 @@ const supportedMimeTypes = [
2048
2136
  imageMimeTypes,
2049
2137
  videoMimeTypes,
2050
2138
  audioMimeTypes,
2051
- /^image\/(svg|svg\+xml)$/
2139
+ /^image\/(svg|svg\+xml)$/,
2140
+ /^message\/rfc822$/
2052
2141
  ];
2053
2142
  const codeInterpreterMimeTypes = [
2054
2143
  textMimeTypes,
@@ -2103,6 +2192,7 @@ const codeTypeMapping = {
2103
2192
  cljs: "text/plain",
2104
2193
  cljc: "text/plain",
2105
2194
  elm: "text/plain",
2195
+ eml: "message/rfc822",
2106
2196
  erl: "text/plain",
2107
2197
  hrl: "text/plain",
2108
2198
  ex: "text/plain",
@@ -2174,6 +2264,13 @@ const codeTypeMapping = {
2174
2264
  ods: "application/vnd.oasis.opendocument.spreadsheet",
2175
2265
  odp: "application/vnd.oasis.opendocument.presentation",
2176
2266
  odg: "application/vnd.oasis.opendocument.graphics",
2267
+ doc: "application/msword",
2268
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
2269
+ xls: "application/vnd.ms-excel",
2270
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
2271
+ ppt: "application/vnd.ms-powerpoint",
2272
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
2273
+ potx: "application/vnd.openxmlformats-officedocument.presentationml.template",
2177
2274
  ics: "text/calendar",
2178
2275
  ical: "text/calendar",
2179
2276
  ifb: "text/calendar",
@@ -2188,7 +2285,11 @@ const imageTypeMapping = {
2188
2285
  const mimeTypeAliases = {
2189
2286
  "application/x-zip-compressed": "application/zip",
2190
2287
  "text/x-python-script": "text/x-python",
2191
- "text/x-markdown": "text/markdown"
2288
+ "text/x-markdown": "text/markdown",
2289
+ /** freedesktop shared-mime-info (Chrome on Linux) */
2290
+ "application/x-shellscript": "application/x-sh",
2291
+ /** libmagic, i.e. `file --mime-type` */
2292
+ "text/x-shellscript": "application/x-sh"
2192
2293
  };
2193
2294
  /**
2194
2295
  * Infers the MIME type from a file's extension when the browser doesn't recognize it,
@@ -2202,7 +2303,7 @@ function inferMimeType(fileName, currentType) {
2202
2303
  const extension = fileName.split(".").pop()?.toLowerCase() ?? "";
2203
2304
  return codeTypeMapping[extension] || imageTypeMapping[extension] || currentType;
2204
2305
  }
2205
- const retrievalMimeTypes = [/^(text\/(x-c|x-c\+\+|x-h|html|x-java|markdown|x-php|x-python|x-script\.python|x-ruby|x-tex|plain|vtt|xml))$/, /^(application\/(json|pdf|vnd\.openxmlformats-officedocument\.(wordprocessingml\.document|presentationml\.presentation)))$/];
2306
+ const retrievalMimeTypes = [/^(text\/(x-c|x-c\+\+|x-h|html|x-java|markdown|x-php|x-python|x-script\.python|x-ruby|x-tex|plain|vtt|xml))$/, /^(application\/(json|pdf|vnd\.openxmlformats-officedocument\.(wordprocessingml\.document|presentationml\.(presentation|template))))$/];
2206
2307
  const megabyte = 1024 * 1024;
2207
2308
  /** Helper function to get megabytes value */
2208
2309
  const mbToBytes = (mb) => mb * megabyte;
@@ -2281,21 +2382,212 @@ const fileConfigSchema = zod.z.object({
2281
2382
  ocr: zod.z.object({ supportedMimeTypes: supportedMimeTypesSchema.optional() }).optional(),
2282
2383
  text: zod.z.object({ supportedMimeTypes: supportedMimeTypesSchema.optional() }).optional()
2283
2384
  });
2284
- /** Helper function to safely convert string patterns to RegExp objects */
2285
- const convertStringsToRegex = (patterns) => patterns.reduce((acc, pattern) => {
2286
- try {
2287
- const regex = new RegExp(pattern);
2288
- acc.push(regex);
2289
- } catch (error) {
2290
- console.error(`Invalid regex pattern "${pattern}" skipped.`, error);
2385
+ /**
2386
+ * Compiler for admin-supplied MIME patterns. Defaults to native `RegExp`, which browser
2387
+ * builds keep so no extra dependency is bundled. The server swaps in a linear-time engine
2388
+ * via `setFileConfigRegexCompiler` so an admin-authored catastrophic-backtracking pattern
2389
+ * cannot ReDoS the shared event loop when tested against an uploaded file's MIME type.
2390
+ */
2391
+ let compileMimeRegex = (pattern) => new RegExp(pattern);
2392
+ /** Override the MIME-pattern compiler; the server injects a linear-time engine at startup. */
2393
+ const setFileConfigRegexCompiler = (compile) => {
2394
+ compileMimeRegex = compile;
2395
+ };
2396
+ /** Returned when every configured pattern fails to compile, so consumers that read an empty
2397
+ * allowlist as "no restriction" fail closed instead of allowing every file. */
2398
+ const rejectAllMimeMatcher = { test: () => false };
2399
+ /** Helper function to safely convert string patterns to matcher objects */
2400
+ const convertStringsToRegex = (patterns) => {
2401
+ const compiled = patterns.reduce((acc, pattern) => {
2402
+ try {
2403
+ acc.push(compileMimeRegex(pattern));
2404
+ } catch (error) {
2405
+ console.error(`Invalid regex pattern "${pattern}" skipped.`, error);
2406
+ }
2407
+ return acc;
2408
+ }, []);
2409
+ if (patterns.length > 0 && compiled.length === 0) {
2410
+ console.error(`All ${patterns.length} MIME type pattern(s) were invalid and skipped; the resulting allowlist rejects every file.`);
2411
+ return [rejectAllMimeMatcher];
2291
2412
  }
2292
- return acc;
2293
- }, []);
2413
+ return compiled;
2414
+ };
2294
2415
  /** Detects whether the given MIME type patterns accept all file types (e.g., `.*` or `.+`). */
2295
2416
  const isPermissiveMimeConfig = (types) => {
2296
2417
  if (!types || types.length === 0) return false;
2297
2418
  return types.some((regex) => regex.test("x-librechat/x-probe"));
2298
2419
  };
2420
+ /** Media categories that collapse to a wildcard `accept` token when any member type is allowed. */
2421
+ const mimeAcceptCategories = [
2422
+ {
2423
+ /** Mirrors `imageMimeTypes` (+ the code-interpreter svg variants) so every accepted type is known. */
2424
+ category: "image",
2425
+ token: "image/*",
2426
+ samples: [
2427
+ "image/jpeg",
2428
+ "image/gif",
2429
+ "image/png",
2430
+ "image/webp",
2431
+ "image/heic",
2432
+ "image/heif",
2433
+ "image/svg",
2434
+ "image/svg+xml"
2435
+ ],
2436
+ extras: [".heif", ".heic"]
2437
+ },
2438
+ {
2439
+ /** Mirrors `audioMimeTypes`. */
2440
+ category: "audio",
2441
+ token: "audio/*",
2442
+ samples: [
2443
+ "audio/mp3",
2444
+ "audio/mpeg",
2445
+ "audio/mpeg3",
2446
+ "audio/wav",
2447
+ "audio/wave",
2448
+ "audio/x-wav",
2449
+ "audio/ogg",
2450
+ "audio/vorbis",
2451
+ "audio/mp4",
2452
+ "audio/m4a",
2453
+ "audio/x-m4a",
2454
+ "audio/flac",
2455
+ "audio/x-flac",
2456
+ "audio/webm",
2457
+ "audio/aac",
2458
+ "audio/wma",
2459
+ "audio/opus"
2460
+ ]
2461
+ },
2462
+ {
2463
+ /** Mirrors `videoMimeTypes`. */
2464
+ category: "video",
2465
+ token: "video/*",
2466
+ samples: [
2467
+ "video/mp4",
2468
+ "video/avi",
2469
+ "video/mov",
2470
+ "video/wmv",
2471
+ "video/flv",
2472
+ "video/webm",
2473
+ "video/mkv",
2474
+ "video/m4v",
2475
+ "video/3gp",
2476
+ "video/ogv"
2477
+ ]
2478
+ }
2479
+ ];
2480
+ /** Document/text MIME types paired with the extension(s) browsers filter on in the file picker. */
2481
+ const documentMimeExtensions = [
2482
+ ["application/pdf", [".pdf"]],
2483
+ ["application/msword", [".doc"]],
2484
+ ["application/vnd.openxmlformats-officedocument.wordprocessingml.document", [".docx"]],
2485
+ ["application/vnd.ms-excel", [".xls"]],
2486
+ ["application/msexcel", [".xls"]],
2487
+ ["application/x-msexcel", [".xls"]],
2488
+ ["application/x-ms-excel", [".xls"]],
2489
+ ["application/x-excel", [".xls"]],
2490
+ ["application/x-dos_ms_excel", [".xls"]],
2491
+ ["application/xls", [".xls"]],
2492
+ ["application/x-xls", [".xls"]],
2493
+ ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", [".xlsx"]],
2494
+ ["application/vnd.ms-powerpoint", [".ppt"]],
2495
+ ["application/vnd.openxmlformats-officedocument.presentationml.presentation", [".pptx"]],
2496
+ ["application/vnd.openxmlformats-officedocument.presentationml.template", [".potx"]],
2497
+ ["application/vnd.oasis.opendocument.text", [".odt"]],
2498
+ ["application/vnd.oasis.opendocument.spreadsheet", [".ods"]],
2499
+ ["application/vnd.oasis.opendocument.presentation", [".odp"]],
2500
+ ["application/vnd.oasis.opendocument.graphics", [".odg"]],
2501
+ ["application/rtf", [".rtf"]],
2502
+ ["application/json", [".json"]],
2503
+ ["application/xml", [".xml"]],
2504
+ ["application/yaml", [".yaml", ".yml"]],
2505
+ ["application/zip", [".zip"]],
2506
+ ["application/x-zip-compressed", [".zip"]],
2507
+ ["application/epub+zip", [".epub"]],
2508
+ ["application/x-parquet", [".parquet"]],
2509
+ ["application/vnd.apache.parquet", [".parquet"]],
2510
+ ["text/csv", [".csv"]],
2511
+ ["application/csv", [".csv"]],
2512
+ ["text/tab-separated-values", [".tsv"]],
2513
+ ["text/plain", [".txt"]],
2514
+ ["text/markdown", [".md"]],
2515
+ ["text/html", [".html", ".htm"]],
2516
+ ["text/calendar", [".ics"]],
2517
+ ["message/rfc822", [".eml"]]
2518
+ ];
2519
+ const documentMimeSet = new Set(documentMimeExtensions.map(([mimeType]) => mimeType));
2520
+ /** Every MIME type LibreChat may accept, used to detect patterns that reach beyond the representable set. */
2521
+ const knownMimeUniverse = Array.from(new Set([
2522
+ ...fullMimeTypesList,
2523
+ ...documentMimeExtensions.map(([mimeType]) => mimeType),
2524
+ ...mimeAcceptCategories.flatMap((category) => category.samples)
2525
+ ]));
2526
+ const categoryOf = (mimeType) => {
2527
+ if (mimeType.startsWith("image/")) return "image";
2528
+ if (mimeType.startsWith("audio/")) return "audio";
2529
+ if (mimeType.startsWith("video/")) return "video";
2530
+ return "document";
2531
+ };
2532
+ /** Media types are covered by their `<cat>/*` wildcard token; document types need an explicit entry. */
2533
+ const isRepresentable = (mimeType) => categoryOf(mimeType) !== "document" || documentMimeSet.has(mimeType);
2534
+ /**
2535
+ * Translates a finite MIME allowlist into a file-input `accept` string, intersected with what the
2536
+ * provider upload path can actually send. Returns `undefined` (keep the provider filter) when a
2537
+ * configured pattern matches a supported, path-handleable type that cannot be represented, so the
2538
+ * picker never hides a file the path would have accepted.
2539
+ */
2540
+ const buildMimeAccept = (types, { categories, documentMimeTypes }) => {
2541
+ const permittedSet = new Set(categories);
2542
+ const documentAllowSet = documentMimeTypes ? new Set(documentMimeTypes) : null;
2543
+ const emittedMedia = /* @__PURE__ */ new Set();
2544
+ const emittedDocuments = /* @__PURE__ */ new Set();
2545
+ if (!types.every((regex) => knownMimeUniverse.some((mimeType) => regex.test(mimeType)))) return;
2546
+ for (const regex of types) for (const mimeType of knownMimeUniverse) {
2547
+ if (!regex.test(mimeType)) continue;
2548
+ const category = categoryOf(mimeType);
2549
+ if (!permittedSet.has(category)) continue;
2550
+ /** The path handles documents but drops this specific type (e.g. Bedrock ignores pptx/ODF). */
2551
+ if (category === "document" && documentAllowSet && !documentAllowSet.has(mimeType)) continue;
2552
+ if (!isRepresentable(mimeType)) return;
2553
+ if (category === "document") emittedDocuments.add(mimeType);
2554
+ else emittedMedia.add(category);
2555
+ }
2556
+ const tokens = [];
2557
+ const seen = /* @__PURE__ */ new Set();
2558
+ const push = (token) => {
2559
+ if (!seen.has(token)) {
2560
+ seen.add(token);
2561
+ tokens.push(token);
2562
+ }
2563
+ };
2564
+ for (const category of mimeAcceptCategories) if (emittedMedia.has(category.category)) {
2565
+ push(category.token);
2566
+ category.extras?.forEach(push);
2567
+ }
2568
+ for (const [mimeType, extensions] of documentMimeExtensions) if (emittedDocuments.has(mimeType)) {
2569
+ extensions.forEach(push);
2570
+ push(mimeType);
2571
+ }
2572
+ return tokens.length > 0 ? tokens.join(",") : void 0;
2573
+ };
2574
+ /**
2575
+ * Resolves the file-input `accept` value for a configured `supportedMimeTypes` allowlist, scoped to
2576
+ * what the current upload path (`capability`) can send to the model.
2577
+ * - `undefined` for the built-in default or a config that can't be represented safely, so callers
2578
+ * keep their provider-specific filter.
2579
+ * - `''` for permissive configs (e.g. `.*`), leaving the picker unrestricted.
2580
+ * - a translated `accept` string for a recognized finite allowlist (images, PDFs, Office docs, etc.).
2581
+ *
2582
+ * The picker `accept` is a UX convenience, not a security boundary: the backend still enforces
2583
+ * `supportedMimeTypes` on upload.
2584
+ */
2585
+ const getConfiguredMimeAccept = (types, capability) => {
2586
+ /** Referential identity with the built-in list signals an unconfigured endpoint (keep provider filter). */
2587
+ if (!types || types.length === 0 || types === supportedMimeTypes) return;
2588
+ if (isPermissiveMimeConfig(types)) return "";
2589
+ return buildMimeAccept(types, capability);
2590
+ };
2299
2591
  /**
2300
2592
  * Gets the appropriate endpoint file configuration with standardized lookup logic.
2301
2593
  *
@@ -2465,8 +2757,16 @@ const messagesArtifacts = (messageId) => `${messagesRoot}/artifact/${messageId}`
2465
2757
  const messagesBranch = () => `${messagesRoot}/branch`;
2466
2758
  const shareRoot = `${BASE_URL}/api/share`;
2467
2759
  const shareMessages = (shareId) => `${shareRoot}/${shareId}`;
2760
+ const forkSharedMessages = (shareId) => `${shareRoot}/${shareId}/fork`;
2761
+ const sharedStartupConfig = (shareId) => `${shareMessages(shareId)}/config`;
2468
2762
  const getSharedLink$1 = (conversationId) => `${shareRoot}/link/${conversationId}`;
2469
- const getSharedLinks = (pageSize, sortBy, sortDirection, search, cursor) => `${shareRoot}?pageSize=${pageSize}&sortBy=${sortBy}&sortDirection=${sortDirection}${search ? `&search=${search}` : ""}${cursor ? `&cursor=${cursor}` : ""}`;
2763
+ const getSharedLinks = (pageSize, sortBy, sortDirection, search, cursor) => `${shareRoot}${buildQuery({
2764
+ pageSize,
2765
+ sortBy,
2766
+ sortDirection,
2767
+ search,
2768
+ cursor
2769
+ })}`;
2470
2770
  const createSharedLink$1 = (conversationId) => `${shareRoot}/${conversationId}`;
2471
2771
  const updateSharedLink$1 = (shareId) => `${shareRoot}/${shareId}`;
2472
2772
  /** Share-scoped file routes: serve snapshotted files via shared-link permission. */
@@ -2506,7 +2806,6 @@ const presets = () => `${BASE_URL}/api/presets`;
2506
2806
  const deletePreset$1 = () => `${BASE_URL}/api/presets/delete`;
2507
2807
  const aiEndpoints = () => `${BASE_URL}/api/endpoints`;
2508
2808
  const tokenConfig = () => `${BASE_URL}/api/endpoints/token-config`;
2509
- const contextProjection = () => `${BASE_URL}/api/endpoints/context-projection`;
2510
2809
  const models = () => `${BASE_URL}/api/models`;
2511
2810
  const tokenizer = () => `${BASE_URL}/api/tokenizer`;
2512
2811
  const login$1 = () => `${BASE_URL}/api/auth/login`;
@@ -2545,6 +2844,7 @@ const mcpAuthValues = (serverName) => {
2545
2844
  const cancelMCPOAuth$1 = (serverName) => {
2546
2845
  return `${BASE_URL}/api/mcp/oauth/cancel/${serverName}`;
2547
2846
  };
2847
+ const mcpOAuthStatus = (flowId) => `${BASE_URL}/api/mcp/oauth/status/${encodeURIComponent(flowId)}`;
2548
2848
  const mcpOAuthBind = (serverName) => `${BASE_URL}/api/mcp/${serverName}/oauth/bind`;
2549
2849
  const actionOAuthBind = (actionId) => `${BASE_URL}/api/actions/${actionId}/oauth/bind`;
2550
2850
  const config = (context) => `${BASE_URL}/api/config${buildQuery({ context })}`;
@@ -2581,6 +2881,8 @@ const mcpServer = (serverName) => `${BASE_URL}/api/mcp/servers/${serverName}`;
2581
2881
  const revertAgentVersion$1 = (agent_id) => `${agents({ path: `${agent_id}/revert` })}`;
2582
2882
  const files = () => `${BASE_URL}/api/files`;
2583
2883
  const filePreview = (fileId) => `${BASE_URL}/api/files/${encodeURIComponent(fileId)}/preview`;
2884
+ /** Owner-scoped usage touch so queued attachments outlive the upload-window TTL. */
2885
+ const fileUsage = () => `${BASE_URL}/api/files/usage`;
2584
2886
  const agentFiles = (agentId) => `${BASE_URL}/api/files/agent/${agentId}`;
2585
2887
  const images = () => `${files()}/images`;
2586
2888
  const avatar = () => `${images()}/avatar`;
@@ -2642,6 +2944,11 @@ const adminSkillsSyncStatus = () => `${adminSkillsSync()}/status`;
2642
2944
  const adminSkillsSyncRun = () => `${adminSkillsSync()}/run`;
2643
2945
  const adminSkillsSyncCredential = (credentialKey) => `${adminSkillsSync()}/credentials/${encodeURIComponent(credentialKey)}`;
2644
2946
  const skillStates = () => `${BASE_URL}/api/user/settings/skills/active`;
2947
+ const adminLangfuseConnection = () => `${BASE_URL}/api/admin/langfuse/connection`;
2948
+ const adminLangfuseConnectionTest = () => `${adminLangfuseConnection()}/test`;
2949
+ const adminLangfuseSessionLink = (conversationId) => `${adminLangfuseConnection()}/session/${encodeURIComponent(conversationId)}`;
2950
+ const toolFavorites = () => `${BASE_URL}/api/user/settings/favorites/tools`;
2951
+ const toolFavorite = (itemType, itemId) => `${toolFavorites()}/${itemType}/${encodeURIComponent(itemId)}`;
2645
2952
  const roles = () => `${BASE_URL}/api/roles`;
2646
2953
  const adminRoles = () => `${BASE_URL}/api/admin/roles`;
2647
2954
  const getRole$1 = (roleName) => `${roles()}/${encodeURIComponent(roleName)}`;
@@ -2666,7 +2973,7 @@ const disableTwoFactor$1 = () => `${BASE_URL}/api/auth/2fa/disable`;
2666
2973
  const regenerateBackupCodes$1 = () => `${BASE_URL}/api/auth/2fa/backup/regenerate`;
2667
2974
  const verifyTwoFactorTemp$1 = () => `${BASE_URL}/api/auth/2fa/verify-temp`;
2668
2975
  const memories = () => `${BASE_URL}/api/memories`;
2669
- const memory = (key) => `${memories()}/${encodeURIComponent(key)}`;
2976
+ const memory = (key, agentId) => `${memories()}/${encodeURIComponent(key)}${agentId ? `?agentId=${encodeURIComponent(agentId)}` : ""}`;
2670
2977
  const memoryPreferences = () => `${memories()}/preferences`;
2671
2978
  const searchPrincipals$1 = (params) => {
2672
2979
  const { q: query, limit, types } = params;
@@ -2949,7 +3256,12 @@ const StdioOptionsSchema = BaseOptionsSchema.extend({
2949
3256
  "pipe",
2950
3257
  "ignore",
2951
3258
  "inherit"
2952
- ]), zod.z.number().int().nonnegative()]).optional()
3259
+ ]), zod.z.number().int().nonnegative()]).optional(),
3260
+ /**
3261
+ * Working directory for the spawned process. Supplied by Agent Plugins
3262
+ * packages, which resolve and contain the path before it reaches this schema.
3263
+ */
3264
+ cwd: zod.z.string().optional()
2953
3265
  });
2954
3266
  const WebSocketOptionsSchema = BaseOptionsSchema.extend({
2955
3267
  type: zod.z.literal("websocket").default("websocket"),
@@ -3085,6 +3397,9 @@ const defaultSocialLogins = [
3085
3397
  "saml"
3086
3398
  ];
3087
3399
  const BASE_ONLY_CONFIG_SECTIONS = [];
3400
+ /** Sections that may be stored in the tenant's base config document but must
3401
+ * not be overridden or tombstoned by role, group, or user config documents. */
3402
+ const BASE_PRINCIPAL_CONFIG_SECTIONS = ["langfuse"];
3088
3403
  const defaultRetrievalModels = [
3089
3404
  "gpt-4o",
3090
3405
  "o1-preview-2024-09-12",
@@ -3168,6 +3483,32 @@ function isPrivateIPv4Literal(value) {
3168
3483
  if (a >= 224) return true;
3169
3484
  return false;
3170
3485
  }
3486
+ /**
3487
+ * Mirrors `hasPrivateEmbeddedIPv4` in `@librechat/api`'s ip helpers: 6to4, NAT64, and Teredo
3488
+ * carry an IPv4 address inside the IPv6 one, and the runtime guard blocks those when the
3489
+ * embedded address is private. Kept in sync so an operator can exempt what the runtime blocks.
3490
+ */
3491
+ function hasPrivateEmbeddedIPv4Literal(value) {
3492
+ const is6to4 = value.startsWith("2002:");
3493
+ const isNat64 = value.startsWith("64:ff9b::");
3494
+ const isTeredo = value.startsWith("2001::");
3495
+ if (!is6to4 && !isNat64 && !isTeredo) return false;
3496
+ const segments = value.split(":").filter((segment) => segment !== "");
3497
+ const pair = is6to4 ? segments.slice(1, 3) : segments.slice(-2);
3498
+ if (pair.length !== 2) return false;
3499
+ const hi = parseInt(pair[0], 16);
3500
+ const lo = parseInt(pair[1], 16);
3501
+ if (isNaN(hi) || isNaN(lo)) return false;
3502
+ /** RFC 4380: Teredo stores the external IPv4 as a bitwise complement. */
3503
+ const high = isTeredo ? ~hi : hi;
3504
+ const low = isTeredo ? ~lo : lo;
3505
+ return isPrivateIPv4Literal([
3506
+ high >> 8 & 255,
3507
+ high & 255,
3508
+ low >> 8 & 255,
3509
+ low & 255
3510
+ ].join("."));
3511
+ }
3171
3512
  function isPrivateIPv6Literal(value) {
3172
3513
  if (!value.includes(":")) return false;
3173
3514
  if (value === "::1" || value === "::") return true;
@@ -3178,7 +3519,7 @@ function isPrivateIPv6Literal(value) {
3178
3519
  }
3179
3520
  const mappedMatch = value.match(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
3180
3521
  if (mappedMatch) return isPrivateIPv4Literal(mappedMatch[1]);
3181
- return false;
3522
+ return hasPrivateEmbeddedIPv4Literal(value);
3182
3523
  }
3183
3524
  /**
3184
3525
  * Mirrors the allowedAddresses parser in `@librechat/api`'s auth helpers.
@@ -3395,6 +3736,7 @@ let AgentCapabilities = /* @__PURE__ */ function(AgentCapabilities) {
3395
3736
  AgentCapabilities["end_after_tools"] = "end_after_tools";
3396
3737
  AgentCapabilities["deferred_tools"] = "deferred_tools";
3397
3738
  AgentCapabilities["execute_code"] = "execute_code";
3739
+ AgentCapabilities["stateful_code_sessions"] = "stateful_code_sessions";
3398
3740
  AgentCapabilities["file_search"] = "file_search";
3399
3741
  AgentCapabilities["web_search"] = "web_search";
3400
3742
  AgentCapabilities["artifacts"] = "artifacts";
@@ -3402,9 +3744,13 @@ let AgentCapabilities = /* @__PURE__ */ function(AgentCapabilities) {
3402
3744
  AgentCapabilities["actions"] = "actions";
3403
3745
  AgentCapabilities["context"] = "context";
3404
3746
  AgentCapabilities["skills"] = "skills";
3747
+ AgentCapabilities["memory"] = "memory";
3748
+ AgentCapabilities["ask_user_question"] = "ask_user_question";
3405
3749
  AgentCapabilities["tools"] = "tools";
3406
3750
  AgentCapabilities["chain"] = "chain";
3407
3751
  AgentCapabilities["ocr"] = "ocr";
3752
+ AgentCapabilities["run_in_background"] = "run_in_background";
3753
+ AgentCapabilities["tool_intents"] = "tool_intents";
3408
3754
  return AgentCapabilities;
3409
3755
  }({});
3410
3756
  const defaultAssistantsVersion = {
@@ -3412,7 +3758,14 @@ const defaultAssistantsVersion = {
3412
3758
  ["azureAssistants"]: 1
3413
3759
  };
3414
3760
  const baseEndpointSchema = zod.z.object({
3415
- streamRate: zod.z.number().optional(),
3761
+ /**
3762
+ * Milliseconds between visible streamed chunks. Agents SDK-backed
3763
+ * providers (openAI, custom, anthropic, google, bedrock, agents) smooth
3764
+ * adaptively at 25ms by default; set to override the cadence, 0 to
3765
+ * disable smoothing. Legacy Assistants and Ollama paths instead sleep
3766
+ * this long per provider chunk (default 1ms), with no adaptive smoothing.
3767
+ */
3768
+ streamRate: zod.z.number().min(0).optional(),
3416
3769
  baseURL: zod.z.string().optional(),
3417
3770
  /**
3418
3771
  * Custom request headers forwarded to the provider on every request. Values
@@ -3440,6 +3793,37 @@ const baseEndpointSchema = zod.z.object({
3440
3793
  * completes (legacy behavior).
3441
3794
  */
3442
3795
  titleTiming: zod.z.union([zod.z.literal("immediate"), zod.z.literal("final")]).optional(),
3796
+ /**
3797
+ * Agent activity groups: collapse each contiguous block of reasoning and
3798
+ * tool calls under a generated one-line header. Mirrors the title options
3799
+ * above — `activityLabel` enables it (like `titleConvo`), the rest tune
3800
+ * the fast model that writes the label.
3801
+ *
3802
+ * NOTE: fields added here reach `endpoints.all` automatically (that schema
3803
+ * is `baseEndpointSchema.omit({ baseURL })`), but NOT Azure — see the
3804
+ * enumerated `.pick()` in `azureEndpointSchema` below.
3805
+ */
3806
+ activityLabel: zod.z.boolean().optional(),
3807
+ /** Model used to write activity labels. Defaults to `titleModel`, then the agent's model. */
3808
+ activityModel: zod.z.string().optional(),
3809
+ /** Endpoint whose credentials the label model runs on. Defaults to the agent's endpoint. */
3810
+ activityEndpoint: zod.z.string().optional(),
3811
+ /** Overrides the system prompt used to write activity labels. */
3812
+ activityPrompt: zod.z.string().optional(),
3813
+ /** Cost cap: maximum labels generated per run. Default 20. */
3814
+ activityMaxPerRun: zod.z.number().int().positive().optional(),
3815
+ /** Per-entry truncation of tool input/output in the label prompt. Default 600. */
3816
+ activityCharLimit: zod.z.number().int().positive().optional(),
3817
+ /** Generates one parent summary for each run phase containing 2+ activities. */
3818
+ activityPhaseLabel: zod.z.boolean().optional(),
3819
+ /** Model used for phase summaries. Defaults to activityModel, titleModel, then the run model. */
3820
+ activityPhaseModel: zod.z.string().optional(),
3821
+ /** Endpoint whose credentials the phase summary model uses. Defaults to activityEndpoint. */
3822
+ activityPhaseEndpoint: zod.z.string().optional(),
3823
+ /** Overrides the dedicated phase-summary system prompt. */
3824
+ activityPhasePrompt: zod.z.string().optional(),
3825
+ /** Cost cap: maximum phase summaries generated per run. Default 5. */
3826
+ activityPhaseMaxPerRun: zod.z.number().int().positive().optional(),
3443
3827
  /** Maximum characters allowed in a single tool result before truncation. */
3444
3828
  maxToolResultChars: zod.z.number().positive().optional()
3445
3829
  });
@@ -3480,6 +3864,11 @@ const assistantEndpointSchema = baseEndpointSchema.merge(zod.z.object({
3480
3864
  "tools"
3481
3865
  ]),
3482
3866
  apiKey: zod.z.string().optional(),
3867
+ /** Masked preview of the API key, stored at write time so admin
3868
+ * reads can show which key is configured without returning the secret.
3869
+ * Shared by both `endpoints.assistants` and `endpoints.azureAssistants`,
3870
+ * which both use this schema. */
3871
+ apiKeyPreview: zod.z.string().optional(),
3483
3872
  models: zod.z.object({
3484
3873
  default: zod.z.array(modelItemSchema).min(1),
3485
3874
  fetch: zod.z.boolean().optional(),
@@ -3497,6 +3886,8 @@ const defaultAgentCapabilities = [
3497
3886
  "actions",
3498
3887
  "context",
3499
3888
  "skills",
3889
+ "memory",
3890
+ "ask_user_question",
3500
3891
  "tools",
3501
3892
  "chain",
3502
3893
  "ocr"
@@ -3542,17 +3933,136 @@ const remoteApiAuthSchema = zod.z.object({
3542
3933
  oidc: remoteApiOidcSchema.optional()
3543
3934
  });
3544
3935
  const remoteApiSchema = zod.z.object({ auth: remoteApiAuthSchema.optional() });
3936
+ /**
3937
+ * Permission mode applied to a tool call. Mirrors `@librechat/agents`'s
3938
+ * `ToolPolicyMode` 1:1.
3939
+ *
3940
+ * - `default`: ask the user about anything not explicitly allowed (default-on).
3941
+ * - `dontAsk`: deny anything not explicitly allowed (headless / API-key flows).
3942
+ * - `bypass`: auto-approve everything that isn't explicitly denied
3943
+ * (the user-facing "stop asking me" toggle).
3944
+ *
3945
+ * Subagents inherit the parent's mode; this is enforced by the SDK and not
3946
+ * overridable per-subagent.
3947
+ */
3948
+ const toolApprovalModeSchema = zod.z.enum([
3949
+ "default",
3950
+ "dontAsk",
3951
+ "bypass"
3952
+ ]);
3953
+ /**
3954
+ * Per-endpoint tool-approval policy.
3955
+ *
3956
+ * Shape mirrors `@librechat/agents`'s `ToolPolicyConfig` so the host can map it
3957
+ * directly into `createToolPolicyHook(config)`. The SDK does the evaluation
3958
+ * (`deny → bypass → allow → ask → dontAsk → fallthrough(ask)`); this config
3959
+ * just describes the surface.
3960
+ *
3961
+ * Conventions:
3962
+ * - All list entries are matched as globs (`*`). Use `mcp:server:*` to scope
3963
+ * a rule to every tool from a single MCP server.
3964
+ * - `deny` always wins, including under `bypass`.
3965
+ * - `enabled: false` is a LibreChat-only kill switch that disables the entire
3966
+ * HITL machinery for this endpoint (no checkpointer, no hooks, no prompts).
3967
+ * This is admin-level; users toggle prompting via `mode: 'bypass'` instead.
3968
+ */
3969
+ /**
3970
+ * A programmatic tool-approval hook loaded from a module at startup.
3971
+ *
3972
+ * The referenced module's default export must be a builder
3973
+ * `(options?) => ToolApprovalHookFactory` (see `@librechat/api`'s `registerToolApprovalHook`).
3974
+ * Hooks compose with the static `allow`/`deny`/`ask` policy above and can only TIGHTEN it
3975
+ * (the SDK folds decisions `deny → ask → allow`). This is admin-level config — the module is
3976
+ * dynamically imported and executed in-process, so only reference trusted code.
3977
+ */
3978
+ const toolApprovalHookConfigSchema = zod.z.object({
3979
+ /**
3980
+ * Module specifier to import: a bare package name (e.g. `@acme/approval-hooks`) or a path —
3981
+ * absolute, or relative to the app root. Its default export is the hook builder.
3982
+ */
3983
+ module: zod.z.string().min(1),
3984
+ /** Optional regex matched against the tool name; omit to run for every tool. */
3985
+ matcher: zod.z.string().optional(),
3986
+ /** Static options forwarded to the module's builder; the hook's own per-call config. */
3987
+ options: zod.z.record(zod.z.unknown()).optional()
3988
+ });
3989
+ const toolApprovalPolicySchema = zod.z.object({
3990
+ enabled: zod.z.boolean().optional(),
3991
+ mode: toolApprovalModeSchema.optional(),
3992
+ allow: zod.z.array(zod.z.string()).optional(),
3993
+ deny: zod.z.array(zod.z.string()).optional(),
3994
+ ask: zod.z.array(zod.z.string()).optional(),
3995
+ /** Optional reason template surfaced in the prompt; `{tool}` is interpolated. */
3996
+ reason: zod.z.string().optional(),
3997
+ /**
3998
+ * Programmatic policy hooks loaded from modules at startup. They layer on top of the
3999
+ * static lists above for dynamic, context-aware decisions the lists can't express
4000
+ * (per-args, per-agent, per-user). See {@link toolApprovalHookConfigSchema}.
4001
+ *
4002
+ * BASE-CONFIG ONLY: hooks are imported + registered once, process-wide, at server
4003
+ * startup — they are NOT reloaded from per-role/user/tenant admin overrides. Encode
4004
+ * per-user/tenant behavior INSIDE the hook (via its runtime context), not by varying the
4005
+ * module list per override. Honored only when `enabled` is true.
4006
+ */
4007
+ hooks: zod.z.array(toolApprovalHookConfigSchema).optional()
4008
+ }).optional();
4009
+ /**
4010
+ * Durable checkpointer backing human-in-the-loop resume.
4011
+ *
4012
+ * When `toolApproval.enabled` is true, a run that pauses for review suspends its
4013
+ * LangGraph state to a checkpoint; resuming rebuilds that state on a *fresh* `Run`
4014
+ * — possibly on a different replica, or the same worker after a restart. That only
4015
+ * works if the checkpoint outlives the original request, so HITL needs a durable
4016
+ * saver, not the SDK's process-local `MemorySaver` fallback.
4017
+ *
4018
+ * Defaults are zero-config: with `toolApproval.enabled` on and no `checkpointer`
4019
+ * block, LibreChat persists checkpoints to its primary MongoDB, so resume works
4020
+ * across replicas out of the box.
4021
+ *
4022
+ * - `type: 'mongo'` (default) — persist to the app database; survives restarts and
4023
+ * resolves on any replica. A TTL index reclaims runs that are never resolved.
4024
+ * - `type: 'memory'` — process-local only. Paused runs do NOT survive a restart and
4025
+ * can only be resolved on the originating worker. Single-process / dev only.
4026
+ */
4027
+ const checkpointerTypeSchema = zod.z.enum(["mongo", "memory"]);
4028
+ const checkpointerSchema = zod.z.object({
4029
+ type: checkpointerTypeSchema.optional(),
4030
+ /**
4031
+ * Approval window, in seconds: how long a paused run waits for a decision
4032
+ * before it is reclaimed. Drives both the Mongo TTL index on checkpoints and
4033
+ * the pending-action expiry, keeping the two layers in lockstep. Defaults to
4034
+ * 86400 (24h). Raise it for longer review windows.
4035
+ */
4036
+ ttl: zod.z.number().int().positive().optional(),
4037
+ /** Advanced: override the Mongo collection names used for checkpoints. */
4038
+ checkpointCollectionName: zod.z.string().optional(),
4039
+ checkpointWritesCollectionName: zod.z.string().optional()
4040
+ }).optional();
3545
4041
  const agentsEndpointSchema = baseEndpointSchema.omit({ baseURL: true }).merge(zod.z.object({
3546
4042
  recursionLimit: zod.z.number().optional(),
3547
4043
  disableBuilder: zod.z.boolean().optional().default(false),
3548
4044
  maxRecursionLimit: zod.z.number().optional(),
4045
+ /** Max cumulative bytes a single streamed tool call's arguments may reach before the run
4046
+ * aborts. Defaults to 64 KiB in the agents SDK; `0` disables the guard. */
4047
+ maxToolCallArgBytes: zod.z.number().optional(),
4048
+ /** Max streamed chunk events per model generation before the run aborts. Off by default. */
4049
+ maxDeltaEventsPerTurn: zod.z.number().optional(),
4050
+ /** Per-tool overrides of `maxToolCallArgBytes`, keyed by model-facing tool name; `0`
4051
+ * disables the guard for that tool only. Merged over LibreChat's shipped default of
4052
+ * `{ create_file: 131072 }`. */
4053
+ maxToolCallArgBytesByTool: zod.z.record(zod.z.number()).optional(),
3549
4054
  maxCitations: zod.z.number().min(1).max(50).optional().default(30),
3550
4055
  maxCitationsPerFile: zod.z.number().min(1).max(10).optional().default(7),
3551
4056
  minRelevanceScore: zod.z.number().min(0).max(1).optional().default(.45),
3552
4057
  allowedProviders: zod.z.array(zod.z.union([zod.z.string(), eModelEndpointSchema])).optional(),
3553
4058
  capabilities: zod.z.array(zod.z.nativeEnum(AgentCapabilities)).optional().default(defaultAgentCapabilities),
3554
4059
  skills: zod.z.object({ maxCatalogSkills: zod.z.number().int().min(1).max(100).optional() }).optional(),
3555
- remoteApi: remoteApiSchema.optional()
4060
+ remoteApi: remoteApiSchema.optional(),
4061
+ /** Human-in-the-loop tool approval policy. Off by default. */
4062
+ toolApproval: toolApprovalPolicySchema,
4063
+ /** Durable checkpointer backing tool-approval and Ask User resume.
4064
+ * Defaults to the app's MongoDB when either flow needs it. */
4065
+ checkpointer: checkpointerSchema
3556
4066
  })).default({
3557
4067
  disableBuilder: false,
3558
4068
  capabilities: defaultAgentCapabilities,
@@ -3611,6 +4121,9 @@ const paramDefinitionSchema = zod.z.object({
3611
4121
  const endpointSchema = baseEndpointSchema.merge(zod.z.object({
3612
4122
  name: zod.z.string().refine((value) => !eModelEndpointSchema.safeParse(value).success, { message: `Value cannot be one of the default endpoint (EModelEndpoint) values: ${Object.values(EModelEndpoint).join(", ")}` }),
3613
4123
  apiKey: zod.z.string(),
4124
+ /** Masked preview of the API key, stored at write time so admin
4125
+ * reads can show which key is configured without returning the secret. */
4126
+ apiKeyPreview: zod.z.string().optional(),
3614
4127
  baseURL: zod.z.string(),
3615
4128
  models: zod.z.object({
3616
4129
  default: zod.z.array(modelItemSchema).min(1),
@@ -3634,6 +4147,10 @@ const endpointSchema = baseEndpointSchema.merge(zod.z.object({
3634
4147
  defaultParamsEndpoint: zod.z.string().default("custom"),
3635
4148
  reasoningFormat: eReasoningParameterFormatSchema.optional(),
3636
4149
  reasoningKey: eReasoningResponseKeySchema.optional(),
4150
+ /** Replays `reasoning_content` within a run's tool-call turns (e.g. Xiaomi MiMo, Kimi). */
4151
+ includeReasoningContent: zod.z.boolean().optional(),
4152
+ /** Also reconstructs `reasoning_content` from persisted history across turns (implies `includeReasoningContent`). */
4153
+ includeReasoningHistory: zod.z.boolean().optional(),
3637
4154
  paramDefinitions: zod.z.array(paramDefinitionSchema).optional()
3638
4155
  }).strict().optional(),
3639
4156
  directEndpoint: zod.z.boolean().optional(),
@@ -3654,15 +4171,35 @@ const endpointSchema = baseEndpointSchema.merge(zod.z.object({
3654
4171
  const azureEndpointSchema = zod.z.object({
3655
4172
  groups: azureGroupConfigsSchema,
3656
4173
  assistants: zod.z.boolean().optional()
3657
- }).and(endpointSchema.pick({
3658
- streamRate: true,
3659
- titleConvo: true,
3660
- titleMethod: true,
3661
- titleModel: true,
3662
- titlePrompt: true,
3663
- titleTiming: true,
3664
- titlePromptTemplate: true
3665
- }).partial());
4174
+ }).and(
4175
+ /**
4176
+ * Azure carries only the base-endpoint fields enumerated here. This is a
4177
+ * `.pick()`, NOT an omit, so a field added to `baseEndpointSchema` is
4178
+ * silently unavailable on Azure endpoints until it is listed below —
4179
+ * unlike `endpoints.all`, which omits and therefore inherits new fields
4180
+ * automatically. Keep this list in sync when adding endpoint options.
4181
+ */
4182
+ endpointSchema.pick({
4183
+ streamRate: true,
4184
+ titleConvo: true,
4185
+ titleMethod: true,
4186
+ titleModel: true,
4187
+ titlePrompt: true,
4188
+ titleTiming: true,
4189
+ titlePromptTemplate: true,
4190
+ activityLabel: true,
4191
+ activityModel: true,
4192
+ activityEndpoint: true,
4193
+ activityPrompt: true,
4194
+ activityMaxPerRun: true,
4195
+ activityCharLimit: true,
4196
+ activityPhaseLabel: true,
4197
+ activityPhaseModel: true,
4198
+ activityPhaseEndpoint: true,
4199
+ activityPhasePrompt: true,
4200
+ activityPhaseMaxPerRun: true
4201
+ }).partial()
4202
+ );
3666
4203
  /**
3667
4204
  * Vertex AI model configuration - similar to Azure model config
3668
4205
  * Allows specifying deployment name for each model
@@ -3698,15 +4235,20 @@ const anthropicEndpointSchema = baseEndpointSchema.merge(zod.z.object({
3698
4235
  /** Optional: List of available models */
3699
4236
  models: zod.z.array(zod.z.string()).optional()
3700
4237
  }));
4238
+ /** Masked preview of the API key, stored at write time so admin
4239
+ * reads can show which key is configured without returning the secret. */
4240
+ const apiKeyPreviewSchema = zod.z.string().optional();
3701
4241
  const ttsOpenaiSchema = zod.z.object({
3702
4242
  url: zod.z.string().optional(),
3703
4243
  apiKey: zod.z.string(),
4244
+ apiKeyPreview: apiKeyPreviewSchema,
3704
4245
  model: zod.z.string(),
3705
4246
  voices: zod.z.array(zod.z.string())
3706
4247
  });
3707
4248
  const ttsAzureOpenAISchema = zod.z.object({
3708
4249
  instanceName: zod.z.string(),
3709
4250
  apiKey: zod.z.string(),
4251
+ apiKeyPreview: apiKeyPreviewSchema,
3710
4252
  deploymentName: zod.z.string(),
3711
4253
  apiVersion: zod.z.string(),
3712
4254
  model: zod.z.string(),
@@ -3716,6 +4258,7 @@ const ttsElevenLabsSchema = zod.z.object({
3716
4258
  url: zod.z.string().optional(),
3717
4259
  websocketUrl: zod.z.string().optional(),
3718
4260
  apiKey: zod.z.string(),
4261
+ apiKeyPreview: apiKeyPreviewSchema,
3719
4262
  model: zod.z.string(),
3720
4263
  voices: zod.z.array(zod.z.string()),
3721
4264
  voice_settings: zod.z.object({
@@ -3729,10 +4272,12 @@ const ttsElevenLabsSchema = zod.z.object({
3729
4272
  const ttsLocalaiSchema = zod.z.object({
3730
4273
  url: zod.z.string(),
3731
4274
  apiKey: zod.z.string().optional(),
4275
+ apiKeyPreview: apiKeyPreviewSchema,
3732
4276
  voices: zod.z.array(zod.z.string()),
3733
4277
  backend: zod.z.string()
3734
4278
  });
3735
4279
  const ttsSchema = zod.z.object({
4280
+ allowedAddresses: allowedAddressesSchema,
3736
4281
  openai: ttsOpenaiSchema.optional(),
3737
4282
  azureOpenAI: ttsAzureOpenAISchema.optional(),
3738
4283
  elevenlabs: ttsElevenLabsSchema.optional(),
@@ -3741,15 +4286,18 @@ const ttsSchema = zod.z.object({
3741
4286
  const sttOpenaiSchema = zod.z.object({
3742
4287
  url: zod.z.string().optional(),
3743
4288
  apiKey: zod.z.string(),
4289
+ apiKeyPreview: apiKeyPreviewSchema,
3744
4290
  model: zod.z.string()
3745
4291
  });
3746
4292
  const sttAzureOpenAISchema = zod.z.object({
3747
4293
  instanceName: zod.z.string(),
3748
4294
  apiKey: zod.z.string(),
4295
+ apiKeyPreview: apiKeyPreviewSchema,
3749
4296
  deploymentName: zod.z.string(),
3750
4297
  apiVersion: zod.z.string()
3751
4298
  });
3752
4299
  const sttSchema = zod.z.object({
4300
+ allowedAddresses: allowedAddressesSchema,
3753
4301
  openai: sttOpenaiSchema.optional(),
3754
4302
  azureOpenAI: sttAzureOpenAISchema.optional()
3755
4303
  });
@@ -3757,16 +4305,23 @@ const speechTab = zod.z.object({
3757
4305
  conversationMode: zod.z.boolean().optional(),
3758
4306
  advancedMode: zod.z.boolean().optional(),
3759
4307
  speechToText: zod.z.boolean().optional().or(zod.z.object({
3760
- /** Keep in sync with STTProviders enum (defined below cannot reference due to eval order) */
3761
- engineSTT: zod.z.enum(["openai", "azureOpenAI"]).optional(),
4308
+ /** Provider names remain valid for backward compatibility and are normalized for clients. */
4309
+ engineSTT: zod.z.enum([
4310
+ "browser",
4311
+ "external",
4312
+ "openai",
4313
+ "azureOpenAI"
4314
+ ]).optional(),
3762
4315
  languageSTT: zod.z.string().optional(),
3763
4316
  autoTranscribeAudio: zod.z.boolean().optional(),
3764
4317
  decibelValue: zod.z.number().optional(),
3765
4318
  autoSendText: zod.z.number().optional()
3766
4319
  })).optional(),
3767
4320
  textToSpeech: zod.z.boolean().optional().or(zod.z.object({
3768
- /** Keep in sync with TTSProviders enum (defined below cannot reference due to eval order) */
4321
+ /** Provider names remain valid for backward compatibility and are normalized for clients. */
3769
4322
  engineTTS: zod.z.enum([
4323
+ "browser",
4324
+ "external",
3770
4325
  "openai",
3771
4326
  "azureOpenAI",
3772
4327
  "elevenlabs",
@@ -4027,18 +4582,25 @@ let SafeSearchTypes = /* @__PURE__ */ function(SafeSearchTypes) {
4027
4582
  return SafeSearchTypes;
4028
4583
  }({});
4029
4584
  const webSearchSchema = zod.z.object({
4585
+ allowedAddresses: allowedAddressesSchema,
4030
4586
  serperApiKey: zod.z.string().optional().default("${SERPER_API_KEY}"),
4587
+ serperApiKeyPreview: apiKeyPreviewSchema,
4031
4588
  searxngInstanceUrl: zod.z.string().optional().default("${SEARXNG_INSTANCE_URL}"),
4032
4589
  searxngApiKey: zod.z.string().optional().default("${SEARXNG_API_KEY}"),
4590
+ searxngApiKeyPreview: apiKeyPreviewSchema,
4033
4591
  firecrawlApiKey: zod.z.string().optional().default("${FIRECRAWL_API_KEY}"),
4592
+ firecrawlApiKeyPreview: apiKeyPreviewSchema,
4034
4593
  firecrawlApiUrl: zod.z.string().optional().default("${FIRECRAWL_API_URL}"),
4035
4594
  firecrawlVersion: zod.z.string().optional().default("${FIRECRAWL_VERSION}"),
4036
4595
  tavilyApiKey: zod.z.string().optional().default("${TAVILY_API_KEY}"),
4596
+ tavilyApiKeyPreview: apiKeyPreviewSchema,
4037
4597
  tavilySearchUrl: zod.z.string().optional().default("${TAVILY_SEARCH_URL}"),
4038
4598
  tavilyExtractUrl: zod.z.string().optional().default("${TAVILY_EXTRACT_URL}"),
4039
4599
  jinaApiKey: zod.z.string().optional().default("${JINA_API_KEY}"),
4600
+ jinaApiKeyPreview: apiKeyPreviewSchema,
4040
4601
  jinaApiUrl: zod.z.string().optional().default("${JINA_API_URL}"),
4041
4602
  cohereApiKey: zod.z.string().optional().default("${COHERE_API_KEY}"),
4603
+ cohereApiKeyPreview: apiKeyPreviewSchema,
4042
4604
  searchProvider: zod.z.nativeEnum(SearchProviders).optional(),
4043
4605
  scraperProvider: zod.z.nativeEnum(ScraperProviders).optional(),
4044
4606
  rerankerType: zod.z.nativeEnum(RerankerTypes).optional(),
@@ -4114,8 +4676,10 @@ const webSearchSchema = zod.z.object({
4114
4676
  }).optional()
4115
4677
  });
4116
4678
  const ocrSchema = zod.z.object({
4679
+ allowedAddresses: allowedAddressesSchema,
4117
4680
  mistralModel: zod.z.string().optional(),
4118
4681
  apiKey: zod.z.string().optional().default("${OCR_API_KEY}"),
4682
+ apiKeyPreview: apiKeyPreviewSchema,
4119
4683
  baseURL: zod.z.string().optional().default("${OCR_BASEURL}"),
4120
4684
  strategy: zod.z.nativeEnum(OCRStrategy).default("mistral_ocr")
4121
4685
  });
@@ -4173,6 +4737,10 @@ const contextPruningSchema = zod.z.object({
4173
4737
  hardClearRatio: zod.z.number().min(0).max(1).optional(),
4174
4738
  minPrunableToolChars: zod.z.number().min(0).optional()
4175
4739
  });
4740
+ const retainRecentConfigSchema = zod.z.object({
4741
+ turns: zod.z.number().min(0).max(20).optional(),
4742
+ tokens: zod.z.number().positive().optional()
4743
+ });
4176
4744
  const summarizationConfigSchema = zod.z.object({
4177
4745
  enabled: zod.z.boolean().optional(),
4178
4746
  provider: zod.z.string().optional(),
@@ -4188,31 +4756,56 @@ const summarizationConfigSchema = zod.z.object({
4188
4756
  updatePrompt: zod.z.string().optional(),
4189
4757
  reserveRatio: zod.z.number().min(0).max(1).optional(),
4190
4758
  maxSummaryTokens: zod.z.number().positive().optional(),
4191
- contextPruning: contextPruningSchema.optional()
4759
+ contextPruning: contextPruningSchema.optional(),
4760
+ retainRecent: retainRecentConfigSchema.optional()
4192
4761
  });
4193
4762
  const customEndpointsSchema = zod.z.array(endpointSchema.partial()).optional();
4763
+ /**
4764
+ * Validates a messageFilter PII regex at config load. Defaults to native RegExp so browser
4765
+ * builds add no extra engine; the server injects a check backed by the linear-time runtime
4766
+ * engine (RE2) via setMessageFilterRegexValidator, so a pattern the runtime cannot compile
4767
+ * (backreferences, lookaround, control escapes, and so on) is rejected at load rather than
4768
+ * silently dropped at request time.
4769
+ */
4770
+ let messageFilterRegexValidator = (value) => {
4771
+ try {
4772
+ new RegExp(value, "g");
4773
+ return true;
4774
+ } catch {
4775
+ return false;
4776
+ }
4777
+ };
4778
+ const setMessageFilterRegexValidator = (validate) => {
4779
+ messageFilterRegexValidator = validate;
4780
+ };
4194
4781
  const messageFilterPiiCustomPatternSchema = zod.z.object({
4195
4782
  id: zod.z.string().min(1),
4196
4783
  label: zod.z.string().min(1),
4197
- regex: zod.z.string().min(1).refine((value) => {
4198
- try {
4199
- new RegExp(value, "g");
4200
- return true;
4201
- } catch {
4202
- return false;
4203
- }
4204
- }, { message: "Invalid regex" })
4784
+ regex: zod.z.string().min(1).refine((value) => messageFilterRegexValidator(value), { message: "Unsupported regex: not compatible with the RE2 engine (no backreferences, lookaround, or control escapes)" })
4205
4785
  });
4206
4786
  const messageFilterPiiSchema = zod.z.object({
4207
4787
  starterPatterns: zod.z.array(zod.z.string()).optional(),
4208
4788
  customPatterns: zod.z.array(messageFilterPiiCustomPatternSchema).optional()
4209
4789
  });
4210
4790
  const messageFilterSchema = zod.z.object({ pii: messageFilterPiiSchema.optional() });
4791
+ const langfuseConfigSchema = zod.z.object({
4792
+ enabled: zod.z.boolean().optional(),
4793
+ publicKey: zod.z.string().optional(),
4794
+ secretKey: zod.z.string().optional(),
4795
+ /** Stable Langfuse project identity returned when credentials are verified. */
4796
+ projectId: zod.z.string().optional(),
4797
+ /** Masked preview of the secret key, stored at write time so
4798
+ * admin reads can show which secret key is configured without returning the secret. */
4799
+ secretKeyPreview: zod.z.string().optional(),
4800
+ /** Routing key for one of the deployment-configured tenant Langfuse destinations. */
4801
+ destination: zod.z.string().optional()
4802
+ });
4211
4803
  const configSchema = zod.z.object({
4212
4804
  version: zod.z.string(),
4213
4805
  cache: zod.z.boolean().default(true),
4214
4806
  ocr: ocrSchema.optional(),
4215
4807
  webSearch: webSearchSchema.optional(),
4808
+ langfuse: langfuseConfigSchema.optional(),
4216
4809
  memory: memorySchema.optional(),
4217
4810
  summarization: summarizationConfigSchema.optional(),
4218
4811
  skillSync: skillSyncConfigSchema,
@@ -4251,6 +4844,13 @@ const configSchema = zod.z.object({
4251
4844
  messageFilter: messageFilterSchema.optional(),
4252
4845
  endpoints: zod.z.object({
4253
4846
  allowedAddresses: allowedAddressesSchema,
4847
+ /**
4848
+ * Defaults applied to every endpoint. Omit-based, so options added to
4849
+ * `baseEndpointSchema` are inherited here automatically — no list to
4850
+ * maintain (contrast `azureEndpointSchema`, which enumerates via
4851
+ * `.pick()`). Resolution order at read sites is `all` > the named
4852
+ * endpoint > a custom endpoint's own config.
4853
+ */
4254
4854
  all: baseEndpointSchema.omit({ baseURL: true }).optional(),
4255
4855
  ["openAI"]: baseEndpointSchema.optional(),
4256
4856
  ["google"]: baseEndpointSchema.optional(),
@@ -4320,6 +4920,9 @@ const alternateName = {
4320
4920
  ["helicone"]: "Helicone"
4321
4921
  };
4322
4922
  const sharedOpenAIModels = [
4923
+ "gpt-5.6",
4924
+ "gpt-5.6-terra",
4925
+ "gpt-5.6-luna",
4323
4926
  "gpt-5.5",
4324
4927
  "gpt-5.5-pro",
4325
4928
  "chat-latest",
@@ -4344,8 +4947,10 @@ const sharedOpenAIModels = [
4344
4947
  ];
4345
4948
  const sharedAnthropicModels = [
4346
4949
  "claude-fable-5",
4950
+ "claude-opus-5",
4347
4951
  "claude-opus-4-8",
4348
4952
  "claude-opus-4-7",
4953
+ "claude-sonnet-5",
4349
4954
  "claude-sonnet-4-6",
4350
4955
  "claude-opus-4-6",
4351
4956
  "claude-sonnet-4-5",
@@ -4366,18 +4971,25 @@ const sharedAnthropicModels = [
4366
4971
  "claude-3-5-sonnet-20240620",
4367
4972
  "claude-3-5-sonnet-latest"
4368
4973
  ];
4974
+ /**
4975
+ * Claude 4+ models are not invocable on-demand by their bare foundation-model
4976
+ * ID on the Converse path — Bedrock rejects those with "Invocation of model ID
4977
+ * ... with on-demand throughput isn't supported. Retry your request with the ID
4978
+ * or ARN of an inference profile that contains this model." Default to the
4979
+ * `global.` cross-region profile (no regional pricing premium, widest
4980
+ * availability); Opus 4.1 has no global profile, so it uses `us.`.
4981
+ */
4369
4982
  const bedrockModels = [
4370
- "anthropic.claude-fable-5",
4371
- "anthropic.claude-opus-4-8",
4372
- "anthropic.claude-opus-4-7",
4373
- "anthropic.claude-sonnet-4-6",
4374
- "anthropic.claude-opus-4-6-v1",
4375
- "anthropic.claude-sonnet-4-5-20250929-v1:0",
4376
- "anthropic.claude-haiku-4-5-20251001-v1:0",
4377
- "anthropic.claude-opus-4-1-20250805-v1:0",
4378
- "anthropic.claude-3-5-sonnet-20241022-v2:0",
4379
- "anthropic.claude-3-5-sonnet-20240620-v1:0",
4380
- "anthropic.claude-3-5-haiku-20241022-v1:0",
4983
+ "global.anthropic.claude-fable-5",
4984
+ "global.anthropic.claude-opus-5",
4985
+ "global.anthropic.claude-opus-4-8",
4986
+ "global.anthropic.claude-opus-4-7",
4987
+ "global.anthropic.claude-sonnet-5",
4988
+ "global.anthropic.claude-sonnet-4-6",
4989
+ "global.anthropic.claude-opus-4-6-v1",
4990
+ "global.anthropic.claude-sonnet-4-5-20250929-v1:0",
4991
+ "global.anthropic.claude-haiku-4-5-20251001-v1:0",
4992
+ "us.anthropic.claude-opus-4-1-20250805-v1:0",
4381
4993
  "cohere.command-r-v1:0",
4382
4994
  "cohere.command-r-plus-v1:0",
4383
4995
  "meta.llama2-13b-chat-v1",
@@ -4402,7 +5014,10 @@ const defaultModels = {
4402
5014
  ["assistants"]: [...sharedOpenAIModels, "chatgpt-4o-latest"],
4403
5015
  ["agents"]: sharedOpenAIModels,
4404
5016
  ["google"]: [
5017
+ "gemini-3.7-flash",
5018
+ "gemini-3.6-flash",
4405
5019
  "gemini-3.5-flash",
5020
+ "gemini-3.5-flash-lite",
4406
5021
  "gemini-3.1-pro-preview",
4407
5022
  "gemini-3.1-pro-preview-customtools",
4408
5023
  "gemini-3.1-flash-lite-preview",
@@ -4562,6 +5177,14 @@ let CacheKeys = /* @__PURE__ */ function(CacheKeys) {
4562
5177
  */
4563
5178
  CacheKeys["ROLES"] = "ROLES";
4564
5179
  /**
5180
+ * Key for cached group memberships used to resolve ACL user principals.
5181
+ */
5182
+ CacheKeys["USER_PRINCIPALS"] = "USER_PRINCIPALS";
5183
+ /**
5184
+ * Key for per-conversation stateful code sandbox prewarm/warm state.
5185
+ */
5186
+ CacheKeys["SANDBOX_PREWARM"] = "SANDBOX_PREWARM";
5187
+ /**
4565
5188
  * Key for the title generation cache.
4566
5189
  */
4567
5190
  CacheKeys["GEN_TITLE"] = "GEN_TITLE";
@@ -4631,6 +5254,10 @@ let CacheKeys = /* @__PURE__ */ function(CacheKeys) {
4631
5254
  */
4632
5255
  CacheKeys["OPENID_EXCHANGED_TOKENS"] = "OPENID_EXCHANGED_TOKENS";
4633
5256
  /**
5257
+ * Key for cached authenticated user documents.
5258
+ */
5259
+ CacheKeys["AUTH_USER_DOC"] = "AUTH_USER_DOC";
5260
+ /**
4634
5261
  * Key for OpenID session.
4635
5262
  */
4636
5263
  CacheKeys["OPENID_SESSION"] = "OPENID_SESSION";
@@ -4644,6 +5271,7 @@ let CacheKeys = /* @__PURE__ */ function(CacheKeys) {
4644
5271
  CacheKeys["ADMIN_OAUTH_EXCHANGE"] = "ADMIN_OAUTH_EXCHANGE";
4645
5272
  return CacheKeys;
4646
5273
  }({});
5274
+ const AUTH_USER_DOC_BY_ID_PREFIX = "auth-user-doc-byid";
4647
5275
  /**
4648
5276
  * Enum for violation types, used to identify, log, and cache violations.
4649
5277
  */
@@ -4767,6 +5395,14 @@ let ErrorTypes = /* @__PURE__ */ function(ErrorTypes) {
4767
5395
  */
4768
5396
  ErrorTypes["GOOGLE_TOOL_CONFLICT"] = "google_tool_conflict";
4769
5397
  /**
5398
+ * Google provider could not process a linked video (most often longer than the model accepts)
5399
+ */
5400
+ ErrorTypes["GOOGLE_VIDEO_UNPROCESSABLE"] = "google_video_unprocessable";
5401
+ /**
5402
+ * Required CodeAPI resources could not be restored before model invocation.
5403
+ */
5404
+ ErrorTypes["RESOURCE_RECOVERY_REQUIRED"] = "resource_recovery_required";
5405
+ /**
4770
5406
  * Invalid Agent Provider (excluded by Admin)
4771
5407
  */
4772
5408
  ErrorTypes["INVALID_AGENT_PROVIDER"] = "invalid_agent_provider";
@@ -4859,6 +5495,10 @@ let SettingsTabValues = /* @__PURE__ */ function(SettingsTabValues) {
4859
5495
  */
4860
5496
  SettingsTabValues["SPEECH"] = "speech";
4861
5497
  /**
5498
+ * Tab for Langfuse Settings
5499
+ */
5500
+ SettingsTabValues["LANGFUSE"] = "langfuse";
5501
+ /**
4862
5502
  * Tab for Beta Features
4863
5503
  */
4864
5504
  SettingsTabValues["BETA"] = "beta";
@@ -4921,7 +5561,7 @@ let TTSProviders = /* @__PURE__ */ function(TTSProviders) {
4921
5561
  /** Enum for app-wide constants */
4922
5562
  let Constants = /* @__PURE__ */ function(Constants) {
4923
5563
  /**
4924
- * Key for the app's version. The placeholder `v0.8.7-rc1` is
5564
+ * Key for the app's version. The placeholder `v0.8.8-rc1` is
4925
5565
  * swapped in by `@rollup/plugin-replace` during `npm run build:data-provider`
4926
5566
  * using the value of the root `package.json`'s `version` field. Consumers
4927
5567
  * always import this via the built dist bundle (see `main` field in
@@ -4929,9 +5569,9 @@ let Constants = /* @__PURE__ */ function(Constants) {
4929
5569
  * substituted value. Only tests that import the TypeScript source directly
4930
5570
  * would observe the raw placeholder.
4931
5571
  */
4932
- Constants["VERSION"] = "v0.8.7-rc1";
5572
+ Constants["VERSION"] = "v0.8.8-rc1";
4933
5573
  /** Key for the Custom Config's version (librechat.yaml). */
4934
- Constants["CONFIG_VERSION"] = "1.3.13";
5574
+ Constants["CONFIG_VERSION"] = "1.3.14";
4935
5575
  /** Standard value for the first message's `parentMessageId` value, to indicate no parent exists. */
4936
5576
  Constants["NO_PARENT"] = "00000000-0000-0000-0000-000000000000";
4937
5577
  /** Standard value to use whatever the submission prelim. `responseMessageId` is */
@@ -4983,8 +5623,126 @@ let Constants = /* @__PURE__ */ function(Constants) {
4983
5623
  Constants["BASH_PROGRAMMATIC_TOOL_CALLING"] = "run_tools_with_bash";
4984
5624
  /** Subagent spawn tool name (must match `@librechat/agents` `Constants.SUBAGENT`). */
4985
5625
  Constants["SUBAGENT"] = "subagent";
5626
+ /** Poll tool for retrieving the status/result of a backgrounded tool call. */
5627
+ Constants["CHECK_BACKGROUND_TASK"] = "check_background_task";
4986
5628
  return Constants;
4987
5629
  }({});
5630
+ /**
5631
+ * Normalizes a server name into the character set tool keys are built from.
5632
+ * Tool keys embed this output, so any candidate list matched against a key must
5633
+ * be normalized the same way.
5634
+ */
5635
+ function normalizeServerName(serverName) {
5636
+ if (/^[a-zA-Z0-9_.-]+$/.test(serverName)) return serverName;
5637
+ const normalized = serverName.replace(/[^a-zA-Z0-9_.-]/g, "_").replace(/^_+|_+$/g, "");
5638
+ if (normalized) return normalized;
5639
+ /** All characters were stripped; hash the original so the name stays unique. */
5640
+ let hash = 0;
5641
+ for (let i = 0; i < serverName.length; i++) {
5642
+ hash = (hash << 5) - hash + serverName.charCodeAt(i);
5643
+ hash |= 0;
5644
+ }
5645
+ return `server_${Math.abs(hash)}`;
5646
+ }
5647
+ /**
5648
+ * Splits a combined MCP tool key (`${rawToolName}${mcp_delimiter}${serverName}`)
5649
+ * back into its two parts.
5650
+ *
5651
+ * Both halves can legitimately contain the delimiter, so position alone cannot
5652
+ * identify the boundary. Raw tool names come from the upstream server and are
5653
+ * untrusted (`get_mcp_server_version`, or a gateway-prefixed
5654
+ * `gitlab-get_mcp_server_version`), and `normalizeServerName` preserves
5655
+ * underscores, so a configured server may be named `Google_mcp_Workspace`.
5656
+ *
5657
+ * When `knownServerNames` is supplied the boundary is resolved against it: the
5658
+ * longest configured name the key actually ends with wins. Otherwise this falls
5659
+ * back to the last delimiter, which is correct whenever only the tool half
5660
+ * contains one and matches `.split()` when neither does.
5661
+ *
5662
+ * One case stays undecidable from the key alone: if both `bar` and `foo_mcp_bar`
5663
+ * are configured, `tool_mcp_foo_mcp_bar` is a valid key for either. Longest match
5664
+ * is the deterministic tiebreak; resolving it properly needs the tool/server
5665
+ * mapping carried alongside the key rather than re-derived from the string.
5666
+ */
5667
+ /**
5668
+ * Maps each configured server name's normalized form back to the raw config
5669
+ * name. Model-facing tool keys embed `normalizeServerName(server)`, while the
5670
+ * registry, config maps, tool cache, and plugin-auth rows are keyed by the raw
5671
+ * name — any consumer that parses a server out of a tool key must resolve it
5672
+ * through this map before those lookups. Identity entries are included so
5673
+ * `aliases.get(name) ?? name` works uniformly.
5674
+ *
5675
+ * When two configured names normalize to the same value their tool keys are
5676
+ * inherently ambiguous; the FIRST configured name wins deterministically here,
5677
+ * and `resolveMCPServerContext` warns about the collision so the operator can
5678
+ * rename one server.
5679
+ */
5680
+ function buildServerNameAliases(rawServerNames) {
5681
+ const aliases = /* @__PURE__ */ new Map();
5682
+ /** Identity entries claim their slot FIRST regardless of configuration
5683
+ * order: a server literally named `foo` must never have its keys rerouted
5684
+ * to a `foo!` whose normalized form collides with it. */
5685
+ for (const raw of rawServerNames) if (raw && normalizeServerName(raw) === raw) aliases.set(raw, raw);
5686
+ for (const raw of rawServerNames) {
5687
+ if (!raw) continue;
5688
+ const normalized = normalizeServerName(raw);
5689
+ if (!aliases.has(normalized)) aliases.set(normalized, raw);
5690
+ }
5691
+ return aliases;
5692
+ }
5693
+ /**
5694
+ * Rewrites a tool key's server segment into the normalized form model-facing
5695
+ * keys carry, resolving the boundary against the configured raw names (longest
5696
+ * suffix wins, mirroring {@link splitMCPToolKey}). Returns the key unchanged
5697
+ * when no configured raw name matches — already-normalized keys, placeholder
5698
+ * tokens, and keys for servers that are no longer configured all pass through.
5699
+ * Idempotent: a normalized segment never matches a raw candidate that needs
5700
+ * rewriting.
5701
+ */
5702
+ function normalizeMCPToolKey(toolKey, rawServerNames) {
5703
+ let matched;
5704
+ for (let i = 0; i < rawServerNames.length; i++) {
5705
+ const raw = rawServerNames[i];
5706
+ if (!raw || raw.length <= (matched?.length ?? 0)) continue;
5707
+ if (toolKey.endsWith(`_mcp_${raw}`)) matched = raw;
5708
+ }
5709
+ if (matched == null) return toolKey;
5710
+ const normalized = normalizeServerName(matched);
5711
+ if (normalized === matched) return toolKey;
5712
+ return `${toolKey.slice(0, toolKey.length - matched.length)}${normalized}`;
5713
+ }
5714
+ function splitMCPToolKey(toolKey, knownServerNames) {
5715
+ if (knownServerNames?.length) {
5716
+ let matched;
5717
+ for (let i = 0; i < knownServerNames.length; i++) {
5718
+ const serverName = knownServerNames[i];
5719
+ if (!serverName || serverName.length <= (matched?.length ?? 0)) continue;
5720
+ if (toolKey.endsWith(`_mcp_${serverName}`)) matched = serverName;
5721
+ }
5722
+ if (matched != null) return [toolKey.slice(0, toolKey.length - matched.length - 5), matched];
5723
+ }
5724
+ const idx = toolKey.lastIndexOf("_mcp_");
5725
+ if (idx === -1) return [toolKey, void 0];
5726
+ return [toolKey.slice(0, idx), toolKey.slice(idx + 5)];
5727
+ }
5728
+ /**
5729
+ * Splits a tool-call name for display, where the key may be a synthetic MCP OAuth
5730
+ * call (`oauth${mcp_delimiter}${serverName}`) rather than a real tool key.
5731
+ *
5732
+ * A configured server name is authoritative when one matches, because a real tool key
5733
+ * always ends in its server. Only when none matches does the `oauth` prefix decide,
5734
+ * which keeps a genuine upstream tool named `oauth${mcp_delimiter}...` from being read
5735
+ * as a synthetic call while still resolving OAuth prompts for unconfigured servers.
5736
+ */
5737
+ function splitToolCallName(toolCallName, knownServerNames) {
5738
+ if (knownServerNames?.length) {
5739
+ const [toolName, serverName] = splitMCPToolKey(toolCallName, knownServerNames);
5740
+ if (serverName != null && knownServerNames.includes(serverName)) return [toolName, serverName];
5741
+ }
5742
+ const oauthPrefix = `oauth_mcp_`;
5743
+ if (toolCallName.startsWith(oauthPrefix)) return ["oauth", toolCallName.slice(oauthPrefix.length)];
5744
+ return splitMCPToolKey(toolCallName, knownServerNames);
5745
+ }
4988
5746
  /** Maximum explicit subagent hops allowed from any root agent at runtime. */
4989
5747
  const MAX_SUBAGENT_DEPTH = 5;
4990
5748
  /** Maximum unique explicit subagent targets that may be loaded at runtime. */
@@ -5036,6 +5794,8 @@ let LocalStorageKeys = /* @__PURE__ */ function(LocalStorageKeys) {
5036
5794
  LocalStorageKeys["LAST_ARTIFACTS_TOGGLE_"] = "LAST_ARTIFACTS_TOGGLE_";
5037
5795
  /** Last checked toggle for Skills per conversation ID */
5038
5796
  LocalStorageKeys["LAST_SKILLS_TOGGLE_"] = "LAST_SKILLS_TOGGLE_";
5797
+ /** Last checked toggle for Memory per conversation ID */
5798
+ LocalStorageKeys["LAST_MEMORY_TOGGLE_"] = "LAST_MEMORY_TOGGLE_";
5039
5799
  /** Key for the last selected agent provider */
5040
5800
  LocalStorageKeys["LAST_AGENT_PROVIDER"] = "lastAgentProvider";
5041
5801
  /** Key for the last selected agent model */
@@ -5347,19 +6107,21 @@ function hasPermissions(permissions, requiredPermission) {
5347
6107
  let QueryKeys = /* @__PURE__ */ function(QueryKeys) {
5348
6108
  QueryKeys["messages"] = "messages";
5349
6109
  QueryKeys["sharedMessages"] = "sharedMessages";
6110
+ QueryKeys["sharedStartupConfig"] = "sharedStartupConfig";
5350
6111
  QueryKeys["sharedLinks"] = "sharedLinks";
5351
6112
  QueryKeys["allConversations"] = "allConversations";
5352
6113
  QueryKeys["archivedConversations"] = "archivedConversations";
5353
6114
  QueryKeys["searchConversations"] = "searchConversations";
5354
6115
  QueryKeys["conversation"] = "conversation";
5355
6116
  QueryKeys["searchEnabled"] = "searchEnabled";
6117
+ QueryKeys["langfuseConnection"] = "langfuseConnection";
6118
+ QueryKeys["langfuseSessionLink"] = "langfuseSessionLink";
5356
6119
  QueryKeys["user"] = "user";
5357
6120
  QueryKeys["name"] = "name";
5358
6121
  QueryKeys["models"] = "models";
5359
6122
  QueryKeys["balance"] = "balance";
5360
6123
  QueryKeys["endpoints"] = "endpoints";
5361
6124
  QueryKeys["tokenConfig"] = "tokenConfig";
5362
- QueryKeys["contextProjection"] = "contextProjection";
5363
6125
  QueryKeys["presets"] = "presets";
5364
6126
  QueryKeys["searchResults"] = "searchResults";
5365
6127
  QueryKeys["tokenCount"] = "tokenCount";
@@ -5419,17 +6181,20 @@ let QueryKeys = /* @__PURE__ */ function(QueryKeys) {
5419
6181
  QueryKeys["skillFileContent"] = "skillFileContent";
5420
6182
  QueryKeys["skillTree"] = "skillTree";
5421
6183
  QueryKeys["skillNodeContent"] = "skillNodeContent";
5422
- QueryKeys["skillFavorites"] = "skillFavorites";
6184
+ QueryKeys["toolFavorites"] = "toolFavorites";
5423
6185
  QueryKeys["skillStates"] = "skillStates";
5424
6186
  QueryKeys["favorites"] = "favorites";
5425
6187
  return QueryKeys;
5426
6188
  }({});
5427
6189
  const DynamicQueryKeys = { agentFiles: (agentId) => ["agentFiles", agentId] };
5428
6190
  let MutationKeys = /* @__PURE__ */ function(MutationKeys) {
6191
+ MutationKeys["updateLangfuseConnection"] = "updateLangfuseConnection";
6192
+ MutationKeys["testLangfuseConnection"] = "testLangfuseConnection";
5429
6193
  MutationKeys["createAgentApiKey"] = "createAgentApiKey";
5430
6194
  MutationKeys["deleteAgentApiKey"] = "deleteAgentApiKey";
5431
6195
  MutationKeys["fileUpload"] = "fileUpload";
5432
6196
  MutationKeys["fileDelete"] = "fileDelete";
6197
+ MutationKeys["fileUsage"] = "fileUsage";
5433
6198
  MutationKeys["updatePreset"] = "updatePreset";
5434
6199
  MutationKeys["deletePreset"] = "deletePreset";
5435
6200
  MutationKeys["loginUser"] = "loginUser";
@@ -5518,6 +6283,7 @@ const TOKEN_REFRESH_BUFFER_MS = 120 * 1e3;
5518
6283
  const refreshToken = (retry) => _post(refreshToken$1(retry));
5519
6284
  const SHARE_PAGE_PATH_REGEX = /^\/share\/[^/]+\/?$/;
5520
6285
  const SHARED_MESSAGES_PATH_REGEX = /^\/api\/share\/[^/]+$/;
6286
+ const SHARE_FORK_PATH_REGEX = /^\/api\/share\/[^/]+\/fork$/;
5521
6287
  const normalizePathname = (pathname) => pathname.startsWith("/") ? pathname : `/${pathname}`;
5522
6288
  const stripBasePath = (pathname) => {
5523
6289
  const normalizedPathname = normalizePathname(pathname);
@@ -5537,6 +6303,11 @@ const getRequestPathname = (url) => {
5537
6303
  }
5538
6304
  };
5539
6305
  const isSharedMessagesRequest = (url, method) => method?.toLowerCase() === "get" && SHARED_MESSAGES_PATH_REGEX.test(stripBasePath(getRequestPathname(url)));
6306
+ /** The "continue this chat" fork is a deliberate authenticated action initiated
6307
+ * from a share page, so it must reach auth recovery/redirect like the shared
6308
+ * data request — otherwise a logged-out (or cold-loaded) viewer's 401 is
6309
+ * rejected silently instead of routing them through login. */
6310
+ const isShareForkRequest = (url, method) => method?.toLowerCase() === "post" && SHARE_FORK_PATH_REGEX.test(stripBasePath(getRequestPathname(url)));
5540
6311
  const dispatchTokenUpdatedEvent = (token) => {
5541
6312
  setTokenHeader(token);
5542
6313
  clearAuthRedirectStartedAt();
@@ -5635,16 +6406,42 @@ const shouldRefreshBeforeRequest = (url) => {
5635
6406
  const timeUntilExpiry = expiresAt - Date.now();
5636
6407
  return timeUntilExpiry > 0 && timeUntilExpiry <= TOKEN_REFRESH_BUFFER_MS;
5637
6408
  };
6409
+ const refreshBeforeRequest = async (url) => {
6410
+ const state = getAuthRecoveryState();
6411
+ if (state.refreshPromise && !isAuthRecoveryEndpoint(url)) return state.refreshPromise.catch(() => null);
6412
+ if (!shouldRefreshBeforeRequest(url)) return null;
6413
+ return startAuthRecovery(false).catch(() => null);
6414
+ };
6415
+ const withAuthorization = (options, token) => {
6416
+ const headers = new Headers(options?.headers);
6417
+ if (token) headers.set("Authorization", `Bearer ${token}`);
6418
+ return {
6419
+ ...options,
6420
+ headers
6421
+ };
6422
+ };
6423
+ async function _authenticatedFetch(url, options) {
6424
+ if (typeof window === "undefined") return fetch(url, options);
6425
+ const token = await refreshBeforeRequest(url) ?? getBearerToken();
6426
+ const response = await fetch(url, withAuthorization(options, token));
6427
+ if (response.status !== 401 || isAuthRecoveryEndpoint(url) || isAuthRedirectInProgress() || !getBearerToken()) return response;
6428
+ let refreshedToken;
6429
+ try {
6430
+ refreshedToken = await startAuthRecovery(false);
6431
+ } catch {
6432
+ redirectToLoginOnce();
6433
+ return response;
6434
+ }
6435
+ if (!refreshedToken) {
6436
+ redirectToLoginOnce();
6437
+ return response;
6438
+ }
6439
+ await response.body?.cancel().catch(() => void 0);
6440
+ return fetch(url, withAuthorization(options, refreshedToken));
6441
+ }
5638
6442
  if (typeof window !== "undefined") {
5639
6443
  axios.default.interceptors.request.use(async (config) => {
5640
- const state = getAuthRecoveryState();
5641
- if (state.refreshPromise && !isAuthRecoveryEndpoint(config.url)) {
5642
- const token = await state.refreshPromise.catch(() => null);
5643
- if (token) setRequestAuthorizationHeader(config, token);
5644
- return config;
5645
- }
5646
- if (!shouldRefreshBeforeRequest(config.url)) return config;
5647
- const token = await startAuthRecovery(false).catch(() => null);
6444
+ const token = await refreshBeforeRequest(config.url);
5648
6445
  if (token) setRequestAuthorizationHeader(config, token);
5649
6446
  return config;
5650
6447
  });
@@ -5658,7 +6455,7 @@ if (typeof window !== "undefined") {
5658
6455
  /** Skip refresh when the Authorization header has been cleared (e.g. during logout),
5659
6456
  * but allow the shared link data request to proceed so private shares can still
5660
6457
  * recover auth/redirect without unrelated share-page queries forcing login. */
5661
- if (!axios.default.defaults.headers.common["Authorization"] && !(isSharePage() && isSharedMessagesRequest(originalRequest.url, originalRequest.method))) return Promise.reject(error);
6458
+ if (!axios.default.defaults.headers.common["Authorization"] && !(isSharePage() && (isSharedMessagesRequest(originalRequest.url, originalRequest.method) || isShareForkRequest(originalRequest.url, originalRequest.method)))) return Promise.reject(error);
5662
6459
  if (isAuthRedirectInProgress()) return Promise.reject(error);
5663
6460
  if (error.response.status === 401 && !originalRequest._retry) {
5664
6461
  if (!(getAuthRecoveryState().refreshPromise != null)) console.warn("401 error, refreshing token");
@@ -5671,8 +6468,12 @@ if (typeof window !== "undefined") {
5671
6468
  }
5672
6469
  redirectToLoginOnce();
5673
6470
  return Promise.reject(error);
5674
- } catch (err) {
5675
- return Promise.reject(err);
6471
+ } catch {
6472
+ /** A rejected refresh (stale/invalid session → 401/403) must route to
6473
+ * login just like an empty-token refresh, otherwise the original 401
6474
+ * surfaces to the caller (e.g. the share fork button) with no redirect. */
6475
+ redirectToLoginOnce();
6476
+ return Promise.reject(error);
5676
6477
  }
5677
6478
  }
5678
6479
  return Promise.reject(error);
@@ -5688,15 +6489,142 @@ var request_default = {
5688
6489
  delete: _delete,
5689
6490
  deleteWithOptions: _deleteWithOptions,
5690
6491
  patch: _patch,
6492
+ authenticatedFetch: _authenticatedFetch,
5691
6493
  refreshToken,
5692
6494
  dispatchTokenUpdatedEvent
5693
6495
  };
5694
6496
  //#endregion
6497
+ //#region src/upload.ts
6498
+ const EVENT_STREAM_MEDIA_TYPE = "text/event-stream";
6499
+ const HEARTBEAT_TIMEOUT_MS = 15e3;
6500
+ var FileUploadError = class extends Error {
6501
+ constructor(message, fileId, toolResource, displayToUser = false, code = 0) {
6502
+ super(message);
6503
+ this.name = "CustomAppError";
6504
+ this.code = code;
6505
+ this.file_id = fileId;
6506
+ this.tool_resource = toolResource;
6507
+ this.display_to_user = displayToUser;
6508
+ this.response = { data: { message: displayToUser ? message : "" } };
6509
+ }
6510
+ };
6511
+ var UploadCanceledError = class extends Error {
6512
+ constructor(..._args) {
6513
+ super(..._args);
6514
+ this.code = "ERR_CANCELED";
6515
+ }
6516
+ };
6517
+ const getFileId = (formData) => String(formData.get("file_id") ?? "");
6518
+ const getToolResource = (formData) => formData.get("tool_resource") ?? void 0;
6519
+ const parseEvent = (message) => {
6520
+ let type = "message";
6521
+ const data = [];
6522
+ for (const line of message.split(/\r?\n/)) {
6523
+ if (line.startsWith("event:")) {
6524
+ type = line.slice(6).trim();
6525
+ continue;
6526
+ }
6527
+ if (line.startsWith("data:")) data.push(line.slice(5).trimStart());
6528
+ }
6529
+ return {
6530
+ type,
6531
+ data: data.join("\n")
6532
+ };
6533
+ };
6534
+ const createHttpError = async (response, formData) => {
6535
+ let message = `Server responded with status: ${response.status}`;
6536
+ try {
6537
+ message = (await response.json()).message || message;
6538
+ } catch {}
6539
+ return new FileUploadError(message, getFileId(formData), getToolResource(formData), true, response.status);
6540
+ };
6541
+ const createStreamError = (data, formData) => {
6542
+ let error;
6543
+ try {
6544
+ error = JSON.parse(data);
6545
+ } catch {
6546
+ error = { message: data };
6547
+ }
6548
+ return new FileUploadError(error.message || "File upload failed.", error.temp_file_id || getFileId(formData), error.tool_resource || getToolResource(formData), error.display_to_user ?? false, error.code ?? 0);
6549
+ };
6550
+ const readEventStream = async (stream, formData) => {
6551
+ const reader = stream.getReader();
6552
+ const decoder = new TextDecoder();
6553
+ let buffer = "";
6554
+ let result = null;
6555
+ let streamEnded = false;
6556
+ let timeoutError = null;
6557
+ let heartbeatTimer;
6558
+ const resetHeartbeatTimer = () => {
6559
+ clearTimeout(heartbeatTimer);
6560
+ heartbeatTimer = setTimeout(() => {
6561
+ timeoutError = /* @__PURE__ */ new Error("Upload connection timed out waiting for a heartbeat.");
6562
+ reader.cancel(timeoutError);
6563
+ }, HEARTBEAT_TIMEOUT_MS);
6564
+ };
6565
+ resetHeartbeatTimer();
6566
+ try {
6567
+ while (true) {
6568
+ const { value, done } = await reader.read();
6569
+ if (done) {
6570
+ streamEnded = true;
6571
+ if (timeoutError) throw timeoutError;
6572
+ if (result) return result;
6573
+ throw new Error("Upload connection closed before completion.");
6574
+ }
6575
+ buffer += decoder.decode(value, { stream: true });
6576
+ const messages = buffer.split(/\r?\n\r?\n/);
6577
+ buffer = messages.pop() ?? "";
6578
+ for (const message of messages) {
6579
+ const event = parseEvent(message);
6580
+ if (event.type === "heartbeat") {
6581
+ resetHeartbeatTimer();
6582
+ continue;
6583
+ }
6584
+ if (event.type === "error") throw createStreamError(event.data, formData);
6585
+ if (event.type === "data") {
6586
+ result = JSON.parse(event.data);
6587
+ continue;
6588
+ }
6589
+ if (event.type === "close") {
6590
+ if (result) return result;
6591
+ throw new Error("Upload stream closed without a result.");
6592
+ }
6593
+ }
6594
+ }
6595
+ } catch (error) {
6596
+ if (error instanceof Error && error.name === "AbortError") throw new UploadCanceledError("Upload canceled.");
6597
+ throw error;
6598
+ } finally {
6599
+ clearTimeout(heartbeatTimer);
6600
+ if (!streamEnded) await reader.cancel().catch(() => void 0);
6601
+ reader.releaseLock();
6602
+ }
6603
+ };
6604
+ async function uploadEventStream(url, formData, signal) {
6605
+ try {
6606
+ const response = await request_default.authenticatedFetch(url, {
6607
+ method: "POST",
6608
+ body: formData,
6609
+ headers: { Accept: EVENT_STREAM_MEDIA_TYPE },
6610
+ signal: signal ?? void 0
6611
+ });
6612
+ if (!response.ok) throw await createHttpError(response, formData);
6613
+ if (!(response.headers.get("Content-Type")?.toLowerCase() ?? "").includes(EVENT_STREAM_MEDIA_TYPE)) return await response.json();
6614
+ if (!response.body) throw new Error("No upload response body received.");
6615
+ return await readEventStream(response.body, formData);
6616
+ } catch (error) {
6617
+ if (signal?.aborted || error instanceof Error && error.name === "AbortError") throw new UploadCanceledError("Upload canceled.");
6618
+ throw error;
6619
+ }
6620
+ }
6621
+ //#endregion
5695
6622
  //#region src/data-service.ts
5696
6623
  var data_service_exports = /* @__PURE__ */ __exportAll({
5697
6624
  acceptTerms: () => acceptTerms,
5698
6625
  addPromptToGroup: () => addPromptToGroup,
5699
6626
  addTagToConversation: () => addTagToConversation,
6627
+ addToolFavorite: () => addToolFavorite,
5700
6628
  archiveConversation: () => archiveConversation,
5701
6629
  assignConversationToProject: () => assignConversationToProject,
5702
6630
  bindActionOAuth: () => bindActionOAuth,
@@ -5744,6 +6672,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5744
6672
  editArtifact: () => editArtifact,
5745
6673
  enableTwoFactor: () => enableTwoFactor,
5746
6674
  forkConversation: () => forkConversation,
6675
+ forkSharedConversation: () => forkSharedConversation,
5747
6676
  genTitle: () => genTitle,
5748
6677
  getAIEndpoints: () => getAIEndpoints,
5749
6678
  getAccessRoles: () => getAccessRoles,
@@ -5753,6 +6682,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5753
6682
  getAgentById: () => getAgentById,
5754
6683
  getAgentCategories: () => getAgentCategories,
5755
6684
  getAgentFiles: () => getAgentFiles,
6685
+ getAgentVersions: () => getAgentVersions,
5756
6686
  getAllEffectivePermissions: () => getAllEffectivePermissions,
5757
6687
  getAllPromptGroups: () => getAllPromptGroups,
5758
6688
  getAssistantById: () => getAssistantById,
@@ -5763,7 +6693,6 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5763
6693
  getBanner: () => getBanner,
5764
6694
  getCategories: () => getCategories,
5765
6695
  getCodeOutputDownload: () => getCodeOutputDownload,
5766
- getContextProjection: () => getContextProjection,
5767
6696
  getConversationById: () => getConversationById,
5768
6697
  getConversationTags: () => getConversationTags,
5769
6698
  getConversations: () => getConversations,
@@ -5779,9 +6708,12 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5779
6708
  getFiles: () => getFiles,
5780
6709
  getGitHubSkillSyncStatus: () => getGitHubSkillSyncStatus,
5781
6710
  getGraphApiToken: () => getGraphApiToken,
6711
+ getLangfuseConnection: () => getLangfuseConnection,
6712
+ getLangfuseSessionLink: () => getLangfuseSessionLink,
5782
6713
  getLoginGoogle: () => getLoginGoogle,
5783
6714
  getMCPAuthValues: () => getMCPAuthValues,
5784
6715
  getMCPConnectionStatus: () => getMCPConnectionStatus,
6716
+ getMCPOAuthStatus: () => getMCPOAuthStatus,
5785
6717
  getMCPServer: () => getMCPServer,
5786
6718
  getMCPServerConnectionStatus: () => getMCPServerConnectionStatus,
5787
6719
  getMCPServers: () => getMCPServers,
@@ -5804,8 +6736,8 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5804
6736
  getSharedFilePreview: () => getSharedFilePreview,
5805
6737
  getSharedLink: () => getSharedLink,
5806
6738
  getSharedMessages: () => getSharedMessages,
6739
+ getSharedStartupConfig: () => getSharedStartupConfig,
5807
6740
  getSkill: () => getSkill,
5808
- getSkillFavorites: () => getSkillFavorites,
5809
6741
  getSkillFileContent: () => getSkillFileContent,
5810
6742
  getSkillNodeContent: () => getSkillNodeContent,
5811
6743
  getSkillStates: () => getSkillStates,
@@ -5813,6 +6745,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5813
6745
  getStartupConfig: () => getStartupConfig,
5814
6746
  getTokenConfig: () => getTokenConfig,
5815
6747
  getToolCalls: () => getToolCalls,
6748
+ getToolFavorites: () => getToolFavorites,
5816
6749
  getUser: () => getUser,
5817
6750
  getUserBalance: () => getUserBalance,
5818
6751
  getUserTerms: () => getUserTerms,
@@ -5833,12 +6766,14 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5833
6766
  login: () => login,
5834
6767
  logout: () => logout,
5835
6768
  makePromptProduction: () => makePromptProduction,
6769
+ markFilesUsage: () => markFilesUsage,
5836
6770
  pinConversation: () => pinConversation,
5837
6771
  rebuildConversationTags: () => rebuildConversationTags,
5838
6772
  recordPromptGroupUsage: () => recordPromptGroupUsage,
5839
6773
  regenerateBackupCodes: () => regenerateBackupCodes,
5840
6774
  register: () => register,
5841
6775
  reinitializeMCPServer: () => reinitializeMCPServer,
6776
+ removeToolFavorite: () => removeToolFavorite,
5842
6777
  requestPasswordReset: () => requestPasswordReset,
5843
6778
  resendVerificationEmail: () => resendVerificationEmail,
5844
6779
  resetPassword: () => resetPassword,
@@ -5849,6 +6784,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5849
6784
  searchPrincipals: () => searchPrincipals,
5850
6785
  setGitHubSkillSyncCredential: () => setGitHubSkillSyncCredential,
5851
6786
  speechToText: () => speechToText,
6787
+ testLangfuseConnection: () => testLangfuseConnection,
5852
6788
  textToSpeech: () => textToSpeech,
5853
6789
  updateAction: () => updateAction,
5854
6790
  updateAgent: () => updateAgent,
@@ -5859,6 +6795,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5859
6795
  updateConversationTag: () => updateConversationTag,
5860
6796
  updateFavorites: () => updateFavorites,
5861
6797
  updateFeedback: () => updateFeedback,
6798
+ updateLangfuseConnection: () => updateLangfuseConnection,
5862
6799
  updateMCPServer: () => updateMCPServer,
5863
6800
  updateMCPServersPermissions: () => updateMCPServersPermissions,
5864
6801
  updateMarketplacePermissions: () => updateMarketplacePermissions,
@@ -5877,7 +6814,6 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5877
6814
  updateResourcePermissions: () => updateResourcePermissions,
5878
6815
  updateSharedLink: () => updateSharedLink,
5879
6816
  updateSkill: () => updateSkill,
5880
- updateSkillFavorites: () => updateSkillFavorites,
5881
6817
  updateSkillNode: () => updateSkillNode,
5882
6818
  updateSkillNodeContent: () => updateSkillNodeContent,
5883
6819
  updateSkillPermissions: () => updateSkillPermissions,
@@ -5896,6 +6832,18 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5896
6832
  verifyTwoFactor: () => verifyTwoFactor,
5897
6833
  verifyTwoFactorTemp: () => verifyTwoFactorTemp
5898
6834
  });
6835
+ function getLangfuseConnection() {
6836
+ return request_default.get(adminLangfuseConnection());
6837
+ }
6838
+ function updateLangfuseConnection(payload) {
6839
+ return request_default.put(adminLangfuseConnection(), payload);
6840
+ }
6841
+ function testLangfuseConnection(payload) {
6842
+ return request_default.post(adminLangfuseConnectionTest(), payload);
6843
+ }
6844
+ function getLangfuseSessionLink(conversationId) {
6845
+ return request_default.get(adminLangfuseSessionLink(conversationId));
6846
+ }
5899
6847
  function revokeUserKey(name) {
5900
6848
  return request_default.delete(revokeUserKey$1(name));
5901
6849
  }
@@ -5911,16 +6859,15 @@ function getFavorites() {
5911
6859
  function updateFavorites(favorites) {
5912
6860
  return request_default.post(`${apiBaseUrl()}/api/user/settings/favorites`, { favorites });
5913
6861
  }
5914
- /**
5915
- * Skill favorites (star-a-skill). The backend route is phase 2 — see the
5916
- * original UI PR for the client surface. Until then, these resolve with
5917
- * an empty list so the UI hooks compile and the Star button is a no-op.
5918
- */
5919
- function getSkillFavorites() {
5920
- return Promise.resolve([]);
6862
+ /** Tool favorites — starred marketplace items (builtins, tools, MCP servers, skills). */
6863
+ function getToolFavorites() {
6864
+ return request_default.get(toolFavorites());
5921
6865
  }
5922
- function updateSkillFavorites(skillFavorites) {
5923
- return Promise.resolve(skillFavorites);
6866
+ function addToolFavorite(favorite) {
6867
+ return request_default.put(toolFavorite(favorite.itemType, favorite.itemId));
6868
+ }
6869
+ function removeToolFavorite(favorite) {
6870
+ return request_default.delete(toolFavorite(favorite.itemType, favorite.itemId));
5924
6871
  }
5925
6872
  /** Per-user skill active/inactive overrides. */
5926
6873
  function getSkillStates() {
@@ -5932,6 +6879,9 @@ function updateSkillStates(skillStates$1) {
5932
6879
  function getSharedMessages(shareId) {
5933
6880
  return request_default.get(shareMessages(shareId));
5934
6881
  }
6882
+ function getSharedStartupConfig(shareId) {
6883
+ return request_default.get(sharedStartupConfig(shareId));
6884
+ }
5935
6885
  const listSharedLinks = async (params) => {
5936
6886
  const { pageSize, sortBy, sortDirection, search, cursor } = params;
5937
6887
  return request_default.get(getSharedLinks(pageSize, sortBy, sortDirection, search, cursor));
@@ -6044,6 +6994,9 @@ const getMCPAuthValues = (serverName) => {
6044
6994
  function cancelMCPOAuth(serverName) {
6045
6995
  return request_default.post(cancelMCPOAuth$1(serverName), {});
6046
6996
  }
6997
+ function getMCPOAuthStatus(flowId) {
6998
+ return request_default.get(mcpOAuthStatus(flowId));
6999
+ }
6047
7000
  const getStartupConfig = (options) => {
6048
7001
  return request_default.get(config(options?.context));
6049
7002
  };
@@ -6053,9 +7006,6 @@ const getAIEndpoints = () => {
6053
7006
  const getTokenConfig = () => {
6054
7007
  return request_default.get(tokenConfig());
6055
7008
  };
6056
- const getContextProjection = (payload) => {
6057
- return request_default.post(contextProjection(), payload);
6058
- };
6059
7009
  const getModels = async () => {
6060
7010
  return request_default.get(models());
6061
7011
  };
@@ -6155,14 +7105,24 @@ const getAgentFiles = (agentId) => {
6155
7105
  const getFileConfig = () => {
6156
7106
  return request_default.get(`${files()}/config`);
6157
7107
  };
6158
- const uploadImage = (data, signal) => {
7108
+ const uploadImage = (data, signal, sseEnabled = false) => {
6159
7109
  const requestConfig = signal ? { signal } : void 0;
7110
+ if (sseEnabled) return uploadEventStream(images(), data, signal);
6160
7111
  return request_default.postMultiPart(images(), data, requestConfig);
6161
7112
  };
6162
- const uploadFile = (data, signal) => {
7113
+ const uploadFile = (data, signal, sseEnabled = false) => {
6163
7114
  const requestConfig = signal ? { signal } : void 0;
7115
+ if (sseEnabled) return uploadEventStream(files(), data, signal);
6164
7116
  return request_default.postMultiPart(files(), data, requestConfig);
6165
7117
  };
7118
+ /**
7119
+ * Marks uploaded files as used (owner-scoped TTL touch) so the upload-window
7120
+ * TTL cannot reap attachments held in a client-side queue during a long run.
7121
+ * Best-effort: callers fire-and-forget — send-time marking is the backstop.
7122
+ */
7123
+ const markFilesUsage = (body) => {
7124
+ return request_default.post(fileUsage(), body);
7125
+ };
6166
7126
  const updateAction = (data) => {
6167
7127
  const { assistant_id, version, ...body } = data;
6168
7128
  return request_default.post(assistants({
@@ -6190,6 +7150,9 @@ const getAgentById = ({ agent_id }) => {
6190
7150
  const getExpandedAgentById = ({ agent_id }) => {
6191
7151
  return request_default.get(agents({ path: `${agent_id}/expanded` }));
6192
7152
  };
7153
+ const getAgentVersions = ({ agent_id }) => {
7154
+ return request_default.get(agents({ path: `${agent_id}/versions` }));
7155
+ };
6193
7156
  const updateAgent = ({ agent_id, data }) => {
6194
7157
  return request_default.patch(agents({ path: agent_id }), data);
6195
7158
  };
@@ -6324,6 +7287,12 @@ function duplicateConversation(payload) {
6324
7287
  function forkConversation(payload) {
6325
7288
  return request_default.post(forkConversation$1(), payload);
6326
7289
  }
7290
+ function forkSharedConversation(shareId, targetMessageIndex, shareRevision) {
7291
+ return request_default.post(forkSharedMessages(shareId), {
7292
+ targetMessageIndex,
7293
+ shareRevision
7294
+ });
7295
+ }
6327
7296
  function deleteConversation(payload) {
6328
7297
  return request_default.deleteWithOptions(deleteConversation$1(), { data: { arg: payload } });
6329
7298
  }
@@ -6638,11 +7607,11 @@ function verifyTwoFactorTemp(payload) {
6638
7607
  const getMemories = () => {
6639
7608
  return request_default.get(memories());
6640
7609
  };
6641
- const deleteMemory = (key) => {
6642
- return request_default.delete(memory(key));
7610
+ const deleteMemory = (key, agentId) => {
7611
+ return request_default.delete(memory(key, agentId));
6643
7612
  };
6644
- const updateMemory = (key, value, originalKey) => {
6645
- return request_default.patch(memory(originalKey || key), {
7613
+ const updateMemory = (key, value, originalKey, agentId) => {
7614
+ return request_default.patch(memory(originalKey || key, agentId), {
6646
7615
  key,
6647
7616
  value
6648
7617
  });
@@ -6681,6 +7650,12 @@ const getActiveJobs = () => {
6681
7650
  return request_default.get(activeJobs());
6682
7651
  };
6683
7652
  //#endregion
7653
+ Object.defineProperty(exports, "AUTH_USER_DOC_BY_ID_PREFIX", {
7654
+ enumerable: true,
7655
+ get: function() {
7656
+ return AUTH_USER_DOC_BY_ID_PREFIX;
7657
+ }
7658
+ });
6684
7659
  Object.defineProperty(exports, "AccessRoleIds", {
6685
7660
  enumerable: true,
6686
7661
  get: function() {
@@ -6741,6 +7716,12 @@ Object.defineProperty(exports, "BASE_ONLY_CONFIG_SECTIONS", {
6741
7716
  return BASE_ONLY_CONFIG_SECTIONS;
6742
7717
  }
6743
7718
  });
7719
+ Object.defineProperty(exports, "BASE_PRINCIPAL_CONFIG_SECTIONS", {
7720
+ enumerable: true,
7721
+ get: function() {
7722
+ return BASE_PRINCIPAL_CONFIG_SECTIONS;
7723
+ }
7724
+ });
6744
7725
  Object.defineProperty(exports, "BedrockProviders", {
6745
7726
  enumerable: true,
6746
7727
  get: function() {
@@ -6963,6 +7944,12 @@ Object.defineProperty(exports, "MYTHOS_CLASS_FAMILIES", {
6963
7944
  return MYTHOS_CLASS_FAMILIES;
6964
7945
  }
6965
7946
  });
7947
+ Object.defineProperty(exports, "MemoryScope", {
7948
+ enumerable: true,
7949
+ get: function() {
7950
+ return MemoryScope;
7951
+ }
7952
+ });
6966
7953
  Object.defineProperty(exports, "MessageContentTypes", {
6967
7954
  enumerable: true,
6968
7955
  get: function() {
@@ -7029,12 +8016,24 @@ Object.defineProperty(exports, "RateLimitPrefix", {
7029
8016
  return RateLimitPrefix;
7030
8017
  }
7031
8018
  });
8019
+ Object.defineProperty(exports, "ReasoningContext", {
8020
+ enumerable: true,
8021
+ get: function() {
8022
+ return ReasoningContext;
8023
+ }
8024
+ });
7032
8025
  Object.defineProperty(exports, "ReasoningEffort", {
7033
8026
  enumerable: true,
7034
8027
  get: function() {
7035
8028
  return ReasoningEffort;
7036
8029
  }
7037
8030
  });
8031
+ Object.defineProperty(exports, "ReasoningMode", {
8032
+ enumerable: true,
8033
+ get: function() {
8034
+ return ReasoningMode;
8035
+ }
8036
+ });
7038
8037
  Object.defineProperty(exports, "ReasoningParameterFormat", {
7039
8038
  enumerable: true,
7040
8039
  get: function() {
@@ -7413,6 +8412,12 @@ Object.defineProperty(exports, "bedrockDocumentFormats", {
7413
8412
  return bedrockDocumentFormats;
7414
8413
  }
7415
8414
  });
8415
+ Object.defineProperty(exports, "bedrockDocumentMimeTypes", {
8416
+ enumerable: true,
8417
+ get: function() {
8418
+ return bedrockDocumentMimeTypes;
8419
+ }
8420
+ });
7416
8421
  Object.defineProperty(exports, "bedrockEndpointSchema", {
7417
8422
  enumerable: true,
7418
8423
  get: function() {
@@ -7437,6 +8442,12 @@ Object.defineProperty(exports, "buildLoginRedirectUrl", {
7437
8442
  return buildLoginRedirectUrl;
7438
8443
  }
7439
8444
  });
8445
+ Object.defineProperty(exports, "buildServerNameAliases", {
8446
+ enumerable: true,
8447
+ get: function() {
8448
+ return buildServerNameAliases;
8449
+ }
8450
+ });
7440
8451
  Object.defineProperty(exports, "cacheSubsetProviders", {
7441
8452
  enumerable: true,
7442
8453
  get: function() {
@@ -7455,6 +8466,18 @@ Object.defineProperty(exports, "checkOpenAIStorage", {
7455
8466
  return checkOpenAIStorage;
7456
8467
  }
7457
8468
  });
8469
+ Object.defineProperty(exports, "checkpointerSchema", {
8470
+ enumerable: true,
8471
+ get: function() {
8472
+ return checkpointerSchema;
8473
+ }
8474
+ });
8475
+ Object.defineProperty(exports, "checkpointerTypeSchema", {
8476
+ enumerable: true,
8477
+ get: function() {
8478
+ return checkpointerTypeSchema;
8479
+ }
8480
+ });
7458
8481
  Object.defineProperty(exports, "clearAllConversations", {
7459
8482
  enumerable: true,
7460
8483
  get: function() {
@@ -7665,12 +8688,24 @@ Object.defineProperty(exports, "eModelEndpointSchema", {
7665
8688
  return eModelEndpointSchema;
7666
8689
  }
7667
8690
  });
8691
+ Object.defineProperty(exports, "eReasoningContextSchema", {
8692
+ enumerable: true,
8693
+ get: function() {
8694
+ return eReasoningContextSchema;
8695
+ }
8696
+ });
7668
8697
  Object.defineProperty(exports, "eReasoningEffortSchema", {
7669
8698
  enumerable: true,
7670
8699
  get: function() {
7671
8700
  return eReasoningEffortSchema;
7672
8701
  }
7673
8702
  });
8703
+ Object.defineProperty(exports, "eReasoningModeSchema", {
8704
+ enumerable: true,
8705
+ get: function() {
8706
+ return eReasoningModeSchema;
8707
+ }
8708
+ });
7674
8709
  Object.defineProperty(exports, "eReasoningParameterFormatSchema", {
7675
8710
  enumerable: true,
7676
8711
  get: function() {
@@ -7875,6 +8910,12 @@ Object.defineProperty(exports, "getConfigDefaults", {
7875
8910
  return getConfigDefaults;
7876
8911
  }
7877
8912
  });
8913
+ Object.defineProperty(exports, "getConfiguredMimeAccept", {
8914
+ enumerable: true,
8915
+ get: function() {
8916
+ return getConfiguredMimeAccept;
8917
+ }
8918
+ });
7878
8919
  Object.defineProperty(exports, "getConversationById", {
7879
8920
  enumerable: true,
7880
8921
  get: function() {
@@ -8103,6 +9144,18 @@ Object.defineProperty(exports, "isAgentsEndpoint", {
8103
9144
  return isAgentsEndpoint;
8104
9145
  }
8105
9146
  });
9147
+ Object.defineProperty(exports, "isAnthropicDocumentType", {
9148
+ enumerable: true,
9149
+ get: function() {
9150
+ return isAnthropicDocumentType;
9151
+ }
9152
+ });
9153
+ Object.defineProperty(exports, "isAnthropicTextDocumentType", {
9154
+ enumerable: true,
9155
+ get: function() {
9156
+ return isAnthropicTextDocumentType;
9157
+ }
9158
+ });
8106
9159
  Object.defineProperty(exports, "isAssistantsEndpoint", {
8107
9160
  enumerable: true,
8108
9161
  get: function() {
@@ -8169,6 +9222,12 @@ Object.defineProperty(exports, "isUUID", {
8169
9222
  return isUUID;
8170
9223
  }
8171
9224
  });
9225
+ Object.defineProperty(exports, "langfuseConfigSchema", {
9226
+ enumerable: true,
9227
+ get: function() {
9228
+ return langfuseConfigSchema;
9229
+ }
9230
+ });
8172
9231
  Object.defineProperty(exports, "loginPage", {
8173
9232
  enumerable: true,
8174
9233
  get: function() {
@@ -8241,6 +9300,18 @@ Object.defineProperty(exports, "normalizeEndpointName", {
8241
9300
  return normalizeEndpointName;
8242
9301
  }
8243
9302
  });
9303
+ Object.defineProperty(exports, "normalizeMCPToolKey", {
9304
+ enumerable: true,
9305
+ get: function() {
9306
+ return normalizeMCPToolKey;
9307
+ }
9308
+ });
9309
+ Object.defineProperty(exports, "normalizeServerName", {
9310
+ enumerable: true,
9311
+ get: function() {
9312
+ return normalizeServerName;
9313
+ }
9314
+ });
8244
9315
  Object.defineProperty(exports, "ocrSchema", {
8245
9316
  enumerable: true,
8246
9317
  get: function() {
@@ -8367,6 +9438,12 @@ Object.defineProperty(exports, "resourcePermissionsResponseSchema", {
8367
9438
  return resourcePermissionsResponseSchema;
8368
9439
  }
8369
9440
  });
9441
+ Object.defineProperty(exports, "retainRecentConfigSchema", {
9442
+ enumerable: true,
9443
+ get: function() {
9444
+ return retainRecentConfigSchema;
9445
+ }
9446
+ });
8370
9447
  Object.defineProperty(exports, "retrievalMimeTypes", {
8371
9448
  enumerable: true,
8372
9449
  get: function() {
@@ -8403,6 +9480,18 @@ Object.defineProperty(exports, "setAcceptLanguageHeader", {
8403
9480
  return setAcceptLanguageHeader;
8404
9481
  }
8405
9482
  });
9483
+ Object.defineProperty(exports, "setFileConfigRegexCompiler", {
9484
+ enumerable: true,
9485
+ get: function() {
9486
+ return setFileConfigRegexCompiler;
9487
+ }
9488
+ });
9489
+ Object.defineProperty(exports, "setMessageFilterRegexValidator", {
9490
+ enumerable: true,
9491
+ get: function() {
9492
+ return setMessageFilterRegexValidator;
9493
+ }
9494
+ });
8406
9495
  Object.defineProperty(exports, "setTokenHeader", {
8407
9496
  enumerable: true,
8408
9497
  get: function() {
@@ -8439,6 +9528,18 @@ Object.defineProperty(exports, "specsConfigSchema", {
8439
9528
  return specsConfigSchema;
8440
9529
  }
8441
9530
  });
9531
+ Object.defineProperty(exports, "splitMCPToolKey", {
9532
+ enumerable: true,
9533
+ get: function() {
9534
+ return splitMCPToolKey;
9535
+ }
9536
+ });
9537
+ Object.defineProperty(exports, "splitToolCallName", {
9538
+ enumerable: true,
9539
+ get: function() {
9540
+ return splitToolCallName;
9541
+ }
9542
+ });
8442
9543
  Object.defineProperty(exports, "summarizationConfigSchema", {
8443
9544
  enumerable: true,
8444
9545
  get: function() {
@@ -8559,6 +9660,24 @@ Object.defineProperty(exports, "toMinimalFeedback", {
8559
9660
  return toMinimalFeedback;
8560
9661
  }
8561
9662
  });
9663
+ Object.defineProperty(exports, "toolApprovalHookConfigSchema", {
9664
+ enumerable: true,
9665
+ get: function() {
9666
+ return toolApprovalHookConfigSchema;
9667
+ }
9668
+ });
9669
+ Object.defineProperty(exports, "toolApprovalModeSchema", {
9670
+ enumerable: true,
9671
+ get: function() {
9672
+ return toolApprovalModeSchema;
9673
+ }
9674
+ });
9675
+ Object.defineProperty(exports, "toolApprovalPolicySchema", {
9676
+ enumerable: true,
9677
+ get: function() {
9678
+ return toolApprovalPolicySchema;
9679
+ }
9680
+ });
8562
9681
  Object.defineProperty(exports, "transactionsSchema", {
8563
9682
  enumerable: true,
8564
9683
  get: function() {
@@ -8680,4 +9799,4 @@ Object.defineProperty(exports, "webSearchSchema", {
8680
9799
  }
8681
9800
  });
8682
9801
 
8683
- //# sourceMappingURL=data-service-DN-HeTC-.js.map
9802
+ //# sourceMappingURL=data-service-DOIF4BkW.js.map