librechat-data-provider 0.8.509 → 0.8.522

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 (61) hide show
  1. package/dist/{data-service-BsdHkdKS.mjs → data-service-CaB7saTP.mjs} +2175 -113
  2. package/dist/data-service-CaB7saTP.mjs.map +1 -0
  3. package/dist/{data-service-XTxx76uB.js → data-service-D5kHzBt-.js} +2806 -150
  4. package/dist/data-service-D5kHzBt-.js.map +1 -0
  5. package/dist/index.js +1403 -92
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +1248 -93
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/react-query/index.js +2 -1
  10. package/dist/react-query/index.js.map +1 -1
  11. package/dist/react-query/index.mjs +2 -1
  12. package/dist/react-query/index.mjs.map +1 -1
  13. package/dist/types/accessPermissions.d.ts +4 -0
  14. package/dist/types/actions.d.ts +3 -3
  15. package/dist/types/agentToolOptions.d.ts +11 -0
  16. package/dist/types/api-endpoints.d.ts +28 -2
  17. package/dist/types/bedrock.d.ts +220 -0
  18. package/dist/types/cadence.d.ts +33 -0
  19. package/dist/types/codeEnvRef.d.ts +21 -0
  20. package/dist/types/config.d.ts +13457 -1573
  21. package/dist/types/data-service.d.ts +65 -14
  22. package/dist/types/feedback.d.ts +9 -1
  23. package/dist/types/file-config.d.ts +42 -5
  24. package/dist/types/filters.d.ts +1422 -0
  25. package/dist/types/generate.d.ts +85 -1
  26. package/dist/types/index.d.ts +10 -0
  27. package/dist/types/keys.d.ts +29 -4
  28. package/dist/types/langchain.d.ts +4 -0
  29. package/dist/types/limits.d.ts +13 -0
  30. package/dist/types/mcp.d.ts +338 -228
  31. package/dist/types/messages.d.ts +13 -0
  32. package/dist/types/models.d.ts +840 -68
  33. package/dist/types/parameterSettings.d.ts +7 -3
  34. package/dist/types/parsers.d.ts +13 -1
  35. package/dist/types/permissions.d.ts +42 -1
  36. package/dist/types/providers.d.ts +36 -0
  37. package/dist/types/react-query/react-query-service.d.ts +2 -7
  38. package/dist/types/request.d.ts +4 -2
  39. package/dist/types/roles.d.ts +34 -0
  40. package/dist/types/runSteps.d.ts +59 -0
  41. package/dist/types/schemas.d.ts +1358 -34
  42. package/dist/types/stateful-code.d.ts +7 -0
  43. package/dist/types/types/agents.d.ts +303 -8
  44. package/dist/types/types/assistants.d.ts +170 -7
  45. package/dist/types/types/files.d.ts +29 -8
  46. package/dist/types/types/index.d.ts +2 -0
  47. package/dist/types/types/insights.d.ts +62 -0
  48. package/dist/types/types/mcpServers.d.ts +25 -0
  49. package/dist/types/types/mutations.d.ts +2 -0
  50. package/dist/types/types/queries.d.ts +47 -5
  51. package/dist/types/types/queuedTurns.d.ts +870 -0
  52. package/dist/types/types/runs.d.ts +206 -26
  53. package/dist/types/types/schedules.d.ts +306 -0
  54. package/dist/types/types/skills.d.ts +34 -6
  55. package/dist/types/types/subagents.d.ts +159 -0
  56. package/dist/types/types/web.d.ts +12 -2
  57. package/dist/types/types.d.ts +175 -2
  58. package/dist/types/upload.d.ts +2 -0
  59. package/package.json +7 -5
  60. package/dist/data-service-BsdHkdKS.mjs.map +0 -1
  61. package/dist/data-service-XTxx76uB.js.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import { ZodArray, ZodError, ZodIssueCode, z } from "zod";
2
+ import { RE2JS } from "re2js";
2
3
  import axios from "axios";
3
4
  //#region \0rolldown/runtime.js
4
5
  var __defProp = Object.defineProperty;
@@ -77,6 +78,258 @@ function normalizeEndpointName(name = "") {
77
78
  return name.toLowerCase() === "ollama" ? "ollama" : name;
78
79
  }
79
80
  //#endregion
81
+ //#region src/filters.ts
82
+ const FILTER_PII_STARTER_PATTERNS = [
83
+ "sk_prefix",
84
+ "bearer_header",
85
+ "api_key_header"
86
+ ];
87
+ const MAX_PII_PATTERNS_PER_SOURCE = 256;
88
+ const MAX_PII_PATTERN_LENGTH = 512;
89
+ const MAX_PII_PATTERN_ID_LENGTH = 256;
90
+ const MAX_PII_PATTERN_LABEL_LENGTH = 512;
91
+ const MAX_PII_CUSTOM_REGEX_CHARACTERS = 8192;
92
+ const MAX_PII_CUSTOM_REGEX_INSTRUCTIONS = 8192;
93
+ const MAX_PII_CUSTOM_PATTERNS_TOTAL = 256;
94
+ const MAX_PII_REGEX_SIZE_CACHE_ENTRIES = 512;
95
+ const PII_REGEX_PROGRAM_SIZE_CACHE = /* @__PURE__ */ new Map();
96
+ function getPiiRegexProgramSize(pattern) {
97
+ if (PII_REGEX_PROGRAM_SIZE_CACHE.has(pattern)) return PII_REGEX_PROGRAM_SIZE_CACHE.get(pattern) ?? null;
98
+ let programSize = null;
99
+ let compiled;
100
+ try {
101
+ compiled = RE2JS.compile(pattern);
102
+ const candidate = compiled.programSize();
103
+ if (Number.isSafeInteger(candidate) && candidate > 0) programSize = candidate;
104
+ } catch {
105
+ programSize = null;
106
+ } finally {
107
+ compiled?.reset();
108
+ }
109
+ if (PII_REGEX_PROGRAM_SIZE_CACHE.size >= MAX_PII_REGEX_SIZE_CACHE_ENTRIES) PII_REGEX_PROGRAM_SIZE_CACHE.clear();
110
+ PII_REGEX_PROGRAM_SIZE_CACHE.set(pattern, programSize);
111
+ return programSize;
112
+ }
113
+ const MESSAGE_FILTER_FIELDS = [
114
+ "name",
115
+ "text",
116
+ "summary",
117
+ "quote",
118
+ "answer",
119
+ "decision_response",
120
+ "decision_reason",
121
+ "content_part",
122
+ "attachment_reference",
123
+ "assembled_context"
124
+ ];
125
+ const HITL_MESSAGE_FILTER_FIELDS = [
126
+ "answer",
127
+ "decision_response",
128
+ "decision_reason"
129
+ ];
130
+ const REQUEST_ONLY_MESSAGE_FILTER_FIELDS = new Set(HITL_MESSAGE_FILTER_FIELDS);
131
+ /** Message fields structurally recoverable without exact semantic provenance. */
132
+ const STORED_MESSAGE_FILTER_FIELDS = MESSAGE_FILTER_FIELDS.filter((field) => !REQUEST_ONLY_MESSAGE_FILTER_FIELDS.has(field));
133
+ const PROMPT_FILTER_FIELDS = [
134
+ "name",
135
+ "description",
136
+ "oneliner",
137
+ "category",
138
+ "command",
139
+ "text",
140
+ "preset_text",
141
+ "system",
142
+ "context",
143
+ "instructions",
144
+ "additional_instructions",
145
+ "greeting",
146
+ "example_input",
147
+ "example_output"
148
+ ];
149
+ const AGENT_INSTRUCTION_FILTER_FIELDS = [
150
+ "name",
151
+ "category",
152
+ "description",
153
+ "instructions",
154
+ "additional_instructions",
155
+ "edge_description",
156
+ "edge_prompt",
157
+ "edge_prompt_key",
158
+ "artifacts",
159
+ "support_contact_name",
160
+ "support_contact_email"
161
+ ];
162
+ const CONVERSATION_STARTER_FILTER_FIELDS = ["text"];
163
+ const CONVERSATION_TITLE_FILTER_FIELDS = ["title"];
164
+ const FEEDBACK_FILTER_FIELDS = ["text"];
165
+ const SKILL_FILTER_FIELDS = [
166
+ "name",
167
+ "display_title",
168
+ "description",
169
+ "category",
170
+ "frontmatter",
171
+ "instructions",
172
+ "imported_text",
173
+ "file_name",
174
+ "file_text"
175
+ ];
176
+ const MEMORY_FILTER_FIELDS = [
177
+ "key",
178
+ "value",
179
+ "summary"
180
+ ];
181
+ const FILE_FILTER_FIELDS = [
182
+ "name",
183
+ "content",
184
+ "extracted_text",
185
+ "transcript",
186
+ "uri"
187
+ ];
188
+ const TOOL_ARGUMENT_FILTER_FIELDS = [
189
+ "name",
190
+ "arguments",
191
+ "output"
192
+ ];
193
+ const MODEL_PARAMETER_FILTER_FIELDS = [
194
+ "stop",
195
+ "request_fields",
196
+ "response_format",
197
+ "metadata"
198
+ ];
199
+ const ACTION_METADATA_FILTER_FIELDS = [
200
+ "raw_spec",
201
+ "domain",
202
+ "privacy_policy_url",
203
+ "authorization_type",
204
+ "custom_auth_header",
205
+ "authorization_content_type",
206
+ "authorization_url",
207
+ "client_url",
208
+ "scope",
209
+ "token_exchange_method",
210
+ "api_key",
211
+ "oauth_client_id",
212
+ "oauth_client_secret"
213
+ ];
214
+ const messageFilterFieldSchema = z.enum(MESSAGE_FILTER_FIELDS);
215
+ const promptFilterFieldSchema = z.enum(PROMPT_FILTER_FIELDS);
216
+ const agentInstructionFilterFieldSchema = z.enum(AGENT_INSTRUCTION_FILTER_FIELDS);
217
+ const conversationStarterFilterFieldSchema = z.enum(CONVERSATION_STARTER_FILTER_FIELDS);
218
+ const conversationTitleFilterFieldSchema = z.enum(CONVERSATION_TITLE_FILTER_FIELDS);
219
+ const feedbackFilterFieldSchema = z.enum(FEEDBACK_FILTER_FIELDS);
220
+ const skillFilterFieldSchema = z.enum(SKILL_FILTER_FIELDS);
221
+ const memoryFilterFieldSchema = z.enum(MEMORY_FILTER_FIELDS);
222
+ const fileFilterFieldSchema = z.enum(FILE_FILTER_FIELDS);
223
+ const toolArgumentFilterFieldSchema = z.enum(TOOL_ARGUMENT_FILTER_FIELDS);
224
+ const modelParameterFilterFieldSchema = z.enum(MODEL_PARAMETER_FILTER_FIELDS);
225
+ const filterPiiStarterPatternSchema = z.enum(FILTER_PII_STARTER_PATTERNS);
226
+ const filterPiiActionSchema = z.enum(["block", "audit"]);
227
+ const actionMetadataFilterFieldSchema = z.enum(ACTION_METADATA_FILTER_FIELDS);
228
+ const unattributedAssistantContentSchema = z.enum(["model_output", "inspect"]);
229
+ const userSubmittedMessageFieldPathSchema = z.object({
230
+ path: z.string().startsWith("/").max(2048),
231
+ field: z.enum(HITL_MESSAGE_FILTER_FIELDS)
232
+ }).strict();
233
+ const UNINSPECTABLE_FILE_FIELDS = new Set([
234
+ "content",
235
+ "extracted_text",
236
+ "transcript"
237
+ ]);
238
+ /**
239
+ * An omitted starter selection enables the built-in catalog. An explicit
240
+ * empty selection disables it, so a source is active only when custom rules
241
+ * remain. This mirrors the documented filter semantics without compiling
242
+ * regular expressions.
243
+ */
244
+ function hasActivePiiPatterns(config) {
245
+ return config != null && (config.starterPatterns == null || config.starterPatterns.length > 0 || (config.customPatterns?.length ?? 0) > 0);
246
+ }
247
+ /** Returns whether an active PII rule can inspect at least one candidate field. */
248
+ function hasActivePiiFields(config, candidates) {
249
+ return hasActivePiiPatterns(config) && (config?.fields == null || candidates.some((field) => config.fields?.includes(field)));
250
+ }
251
+ /**
252
+ * Returns whether a parsed source-aware config can enforce any rule. An
253
+ * explicit fail-close file policy remains active even without text patterns.
254
+ */
255
+ function hasActiveFiltersConfig(filters) {
256
+ if (filters == null) return false;
257
+ if (filters.messages?.unattributedAssistantContent === "inspect") return true;
258
+ if ([
259
+ filters.messages?.pii,
260
+ filters.prompts?.pii,
261
+ filters.agentInstructions?.pii,
262
+ filters.conversationStarters?.pii,
263
+ filters.conversationTitles?.pii,
264
+ filters.feedback?.pii,
265
+ filters.skills?.pii,
266
+ filters.memories?.pii,
267
+ filters.files?.pii,
268
+ filters.toolArguments?.pii,
269
+ filters.modelParameters?.pii,
270
+ filters.actionMetadata?.pii
271
+ ].some(hasActivePiiPatterns)) return true;
272
+ const filePii = filters.files?.pii;
273
+ return filePii?.uninspectable === "block" && (filePii.fields == null || filePii.fields.some((field) => UNINSPECTABLE_FILE_FIELDS.has(field)));
274
+ }
275
+ const filterPiiRegexSchema = z.string().min(1).max(512).refine((value) => getPiiRegexProgramSize(value) != null, { message: "Regex must use supported linear-time syntax" });
276
+ const filterPiiCustomPatternSchema = z.object({
277
+ id: z.string().min(1).max(256),
278
+ label: z.string().min(1).max(512),
279
+ regex: filterPiiRegexSchema
280
+ }).strict();
281
+ function createPiiFilterSchema(fieldSchema) {
282
+ return z.object({
283
+ action: filterPiiActionSchema.optional(),
284
+ fields: z.array(fieldSchema).min(1).max(256).optional(),
285
+ starterPatterns: z.array(filterPiiStarterPatternSchema).max(256).optional(),
286
+ customPatterns: z.array(filterPiiCustomPatternSchema).max(256).optional()
287
+ }).strict();
288
+ }
289
+ function createSourceFilterSchema(fieldSchema) {
290
+ return z.object({ pii: createPiiFilterSchema(fieldSchema).optional() }).strict();
291
+ }
292
+ const messageSourceFilterSchema = z.object({
293
+ pii: createPiiFilterSchema(messageFilterFieldSchema).optional(),
294
+ unattributedAssistantContent: unattributedAssistantContentSchema.optional()
295
+ }).strict();
296
+ const fileSourceFilterSchema = z.object({ pii: createPiiFilterSchema(fileFilterFieldSchema).extend({ uninspectable: z.enum(["allow", "block"]).optional() }).optional() }).strict();
297
+ const filtersConfigSchema = z.object({
298
+ messages: messageSourceFilterSchema.optional(),
299
+ prompts: createSourceFilterSchema(promptFilterFieldSchema).optional(),
300
+ agentInstructions: createSourceFilterSchema(agentInstructionFilterFieldSchema).optional(),
301
+ conversationStarters: createSourceFilterSchema(conversationStarterFilterFieldSchema).optional(),
302
+ conversationTitles: createSourceFilterSchema(conversationTitleFilterFieldSchema).optional(),
303
+ feedback: createSourceFilterSchema(feedbackFilterFieldSchema).optional(),
304
+ skills: createSourceFilterSchema(skillFilterFieldSchema).optional(),
305
+ memories: createSourceFilterSchema(memoryFilterFieldSchema).optional(),
306
+ files: fileSourceFilterSchema.optional(),
307
+ toolArguments: createSourceFilterSchema(toolArgumentFilterFieldSchema).optional(),
308
+ modelParameters: createSourceFilterSchema(modelParameterFilterFieldSchema).optional(),
309
+ actionMetadata: createSourceFilterSchema(actionMetadataFilterFieldSchema).optional()
310
+ }).strict().superRefine((filters, context) => {
311
+ let customPatterns = 0;
312
+ let regexCharacters = 0;
313
+ let regexInstructions = 0;
314
+ for (const source of Object.values(filters)) for (const pattern of source?.pii?.customPatterns ?? []) {
315
+ customPatterns++;
316
+ regexCharacters += pattern.regex.length;
317
+ regexInstructions += getPiiRegexProgramSize(pattern.regex) ?? 0;
318
+ }
319
+ if (customPatterns > 256) context.addIssue({
320
+ code: z.ZodIssueCode.custom,
321
+ message: `At most 256 custom PII patterns may be configured in total`
322
+ });
323
+ if (regexCharacters > 8192) context.addIssue({
324
+ code: z.ZodIssueCode.custom,
325
+ message: `Custom PII regexes may contain at most ${MAX_PII_CUSTOM_REGEX_CHARACTERS} characters in total`
326
+ });
327
+ if (regexInstructions > 8192) context.addIssue({
328
+ code: z.ZodIssueCode.custom,
329
+ message: `Custom PII regexes may compile to at most ${MAX_PII_CUSTOM_REGEX_INSTRUCTIONS} instructions in total`
330
+ });
331
+ });
332
+ //#endregion
80
333
  //#region src/feedback.ts
81
334
  const FEEDBACK_RATINGS = ["thumbsUp", "thumbsDown"];
82
335
  const FEEDBACK_REASON_KEYS = [
@@ -169,6 +422,9 @@ const feedbackSchema = z.object({
169
422
  rating: feedbackRatingSchema,
170
423
  tag: feedbackTagKeySchema,
171
424
  text: z.string().max(1024).optional()
425
+ }).refine(({ rating, tag }) => FEEDBACK_TAGS.some((feedbackTag) => feedbackTag.key === tag && feedbackTag.direction === rating), {
426
+ message: "Feedback tag does not match rating",
427
+ path: ["tag"]
172
428
  });
173
429
  function toMinimalFeedback(feedback) {
174
430
  if (!feedback?.rating || !feedback?.tag || !feedback.tag.key) return;
@@ -183,6 +439,25 @@ function getTagByKey(key) {
183
439
  return FEEDBACK_TAGS.find((tag) => tag.key === key);
184
440
  }
185
441
  //#endregion
442
+ //#region src/stateful-code.ts
443
+ const STATEFUL_CODE_ENVIRONMENTS = [
444
+ "user",
445
+ "agent-user",
446
+ "conversation"
447
+ ];
448
+ /** Resolve a deployment allowlist in stable UI order. An omitted value preserves
449
+ * the backward-compatible behavior where every environment is available. */
450
+ function resolveAllowedStatefulCodeEnvironments(configured) {
451
+ if (configured == null) return [...STATEFUL_CODE_ENVIRONMENTS];
452
+ const configuredSet = new Set(configured);
453
+ return STATEFUL_CODE_ENVIRONMENTS.filter((environment) => configuredSet.has(environment));
454
+ }
455
+ /** Keep an allowed preference, otherwise select the first deployment-allowed scope. */
456
+ function resolveStatefulCodeEnvironment(preferred, configured) {
457
+ const allowed = resolveAllowedStatefulCodeEnvironments(configured);
458
+ return preferred != null && allowed.includes(preferred) ? preferred : allowed[0];
459
+ }
460
+ //#endregion
186
461
  //#region src/types/assistants.ts
187
462
  let Tools = /* @__PURE__ */ function(Tools) {
188
463
  Tools["execute_code"] = "execute_code";
@@ -464,6 +739,7 @@ let ReasoningEffort = /* @__PURE__ */ function(ReasoningEffort) {
464
739
  ReasoningEffort["medium"] = "medium";
465
740
  ReasoningEffort["high"] = "high";
466
741
  ReasoningEffort["xhigh"] = "xhigh";
742
+ ReasoningEffort["max"] = "max";
467
743
  return ReasoningEffort;
468
744
  }({});
469
745
  let ReasoningParameterFormat = /* @__PURE__ */ function(ReasoningParameterFormat) {
@@ -530,6 +806,21 @@ let ThinkingLevel = /* @__PURE__ */ function(ThinkingLevel) {
530
806
  ThinkingLevel["high"] = "high";
531
807
  return ThinkingLevel;
532
808
  }({});
809
+ /** OpenAI Responses API `reasoning.mode` (GPT-5.6+). */
810
+ let ReasoningMode = /* @__PURE__ */ function(ReasoningMode) {
811
+ ReasoningMode["unset"] = "";
812
+ ReasoningMode["standard"] = "standard";
813
+ ReasoningMode["pro"] = "pro";
814
+ return ReasoningMode;
815
+ }({});
816
+ /** OpenAI Responses API `reasoning.context` (GPT-5.6+). */
817
+ let ReasoningContext = /* @__PURE__ */ function(ReasoningContext) {
818
+ ReasoningContext["unset"] = "";
819
+ ReasoningContext["auto"] = "auto";
820
+ ReasoningContext["current_turn"] = "current_turn";
821
+ ReasoningContext["all_turns"] = "all_turns";
822
+ return ReasoningContext;
823
+ }({});
533
824
  const imageDetailNumeric = {
534
825
  ["low"]: 0,
535
826
  ["auto"]: 1,
@@ -549,6 +840,8 @@ const eThinkingDisplaySchema = z.nativeEnum(ThinkingDisplay);
549
840
  const eReasoningSummarySchema = z.nativeEnum(ReasoningSummary);
550
841
  const eVerbositySchema = z.nativeEnum(Verbosity);
551
842
  const eThinkingLevelSchema = z.nativeEnum(ThinkingLevel);
843
+ const eReasoningModeSchema = z.nativeEnum(ReasoningMode);
844
+ const eReasoningContextSchema = z.nativeEnum(ReasoningContext);
552
845
  const defaultAssistantFormValues = {
553
846
  assistant: "",
554
847
  id: "",
@@ -580,6 +873,9 @@ const defaultAgentFormValues = {
580
873
  ["execute_code"]: false,
581
874
  ["file_search"]: false,
582
875
  ["web_search"]: false,
876
+ ["memory"]: false,
877
+ stateful_code_environment: "user",
878
+ code_environment_id: void 0,
583
879
  category: "general",
584
880
  support_contact: {
585
881
  name: "",
@@ -591,8 +887,14 @@ const defaultAgentFormValues = {
591
887
  /** Master toggle for skill use on this agent. `true` activates skills
592
888
  * (full catalog unless `skills` narrows it). Anything else = inactive. */
593
889
  skills_enabled: void 0,
890
+ /** Enables runtime skill creation without exposing an existing skill catalog. */
891
+ skill_authoring_enabled: void 0,
892
+ /** Explicit catalog scope. Missing preserves the legacy enabled + empty = all behavior. */
893
+ skills_scope: void 0,
594
894
  /** `undefined` = feature disabled by default (no subagent tool injected). */
595
- subagents: void 0
895
+ subagents: void 0,
896
+ /** Memory partition: 'agent' isolates memories per (user, agent); default shared pool */
897
+ memory_scope: void 0
596
898
  };
597
899
  const ImageVisionTool = {
598
900
  type: "function",
@@ -606,6 +908,8 @@ const ImageVisionTool = {
606
908
  }
607
909
  }
608
910
  };
911
+ /** Structural on purpose: accepts assistants tools/tool calls and agents function tool
912
+ * calls alike — the check only ever reads `type` and `function.name`. */
609
913
  const isImageVisionTool = (tool) => tool.type === "function" && tool.function?.name === ImageVisionTool.function?.name;
610
914
  const openAISettings = {
611
915
  model: { default: "gpt-4o-mini" },
@@ -664,8 +968,45 @@ const getGoogleMaxOutputTokens = (modelName) => {
664
968
  }
665
969
  return GOOGLE_LEGACY_MAX_OUTPUT;
666
970
  };
971
+ /**
972
+ * Per-model thinking budget bounds, documented in
973
+ * `com_endpoint_google_thinking_budget`: Gemini 2.5 Pro accepts 128-32,768,
974
+ * Flash accepts 0-24,576, and Flash Lite accepts 512-24,576. The generic
975
+ * 32,000 in the shared definition both under-limits Pro and lets invalid
976
+ * Flash values through.
977
+ *
978
+ * `-1` remains the "decide automatically" sentinel and is not part of these
979
+ * floors. Callers must keep `range.min` at -1 and apply `min` only to
980
+ * non-negative values.
981
+ */
982
+ const GOOGLE_THINKING_BUDGET_PRO_MAX = 32768;
983
+ const GOOGLE_THINKING_BUDGET_FLASH_MAX = 24576;
984
+ const GOOGLE_THINKING_BUDGET_PRO_MIN = 128;
985
+ const GOOGLE_THINKING_BUDGET_FLASH_MIN = 0;
986
+ const GOOGLE_THINKING_BUDGET_FLASH_LITE_MIN = 512;
987
+ const getGoogleThinkingBudgetBounds = (modelName) => {
988
+ if (!/gemini-2\.5/i.test(modelName)) return;
989
+ if (/flash[-_.]?lite/i.test(modelName)) return {
990
+ min: GOOGLE_THINKING_BUDGET_FLASH_LITE_MIN,
991
+ max: GOOGLE_THINKING_BUDGET_FLASH_MAX
992
+ };
993
+ if (/flash/i.test(modelName)) return {
994
+ min: GOOGLE_THINKING_BUDGET_FLASH_MIN,
995
+ max: GOOGLE_THINKING_BUDGET_FLASH_MAX
996
+ };
997
+ if (/pro/i.test(modelName)) return {
998
+ min: GOOGLE_THINKING_BUDGET_PRO_MIN,
999
+ max: GOOGLE_THINKING_BUDGET_PRO_MAX
1000
+ };
1001
+ };
1002
+ const getGoogleThinkingBudgetMax = (modelName) => getGoogleThinkingBudgetBounds(modelName)?.max;
667
1003
  const googleSettings = {
668
1004
  model: { default: "gemini-1.5-flash-latest" },
1005
+ maxContextTokens: {
1006
+ min: 10,
1007
+ max: 2e6,
1008
+ step: 1e3
1009
+ },
669
1010
  maxOutputTokens: {
670
1011
  min: 1,
671
1012
  max: GOOGLE_MAX_OUTPUT,
@@ -712,6 +1053,7 @@ const CLAUDE_4_64K_MAX_OUTPUT = 64e3;
712
1053
  const CLAUDE_32K_MAX_OUTPUT = 32e3;
713
1054
  const DEFAULT_MAX_OUTPUT = 8192;
714
1055
  const LEGACY_ANTHROPIC_MAX_OUTPUT = 4096;
1056
+ const CLAUDE_SONNET_128K_OUTPUT_PATTERN = /claude-sonnet[-.]?(?:4[-.]?(?:[6-9]|\d{2})|[5-9]|\d{2,})(?=$|[^0-9])/;
715
1057
  /**
716
1058
  * Claude "Mythos-class" model families — new top-level classes (peers of
717
1059
  * `opus`/`sonnet`/`haiku`) that ship with the post-Opus-4.7 modern profile:
@@ -755,6 +1097,7 @@ const anthropicSettings = {
755
1097
  reset: (modelName) => {
756
1098
  if (isMythosClassModel(modelName)) return ANTHROPIC_MAX_OUTPUT;
757
1099
  if (/claude-opus[-.]?(?:4[-.]?(?:[6-9]|\d{2,})|[5-9]|\d{2,})/.test(modelName)) return ANTHROPIC_MAX_OUTPUT;
1100
+ if (CLAUDE_SONNET_128K_OUTPUT_PATTERN.test(modelName)) return ANTHROPIC_MAX_OUTPUT;
758
1101
  if (/claude-(?:sonnet|haiku)[-.]?[4-9]/.test(modelName)) return CLAUDE_4_64K_MAX_OUTPUT;
759
1102
  if (/claude-opus[-.]?(?:[5-9]|4[-.]?([5-9]|\d{2,}))/.test(modelName)) return CLAUDE_4_64K_MAX_OUTPUT;
760
1103
  if (/claude-opus[-.]?[4-9]/.test(modelName)) return CLAUDE_32K_MAX_OUTPUT;
@@ -769,6 +1112,10 @@ const anthropicSettings = {
769
1112
  if (value > ANTHROPIC_MAX_OUTPUT) return ANTHROPIC_MAX_OUTPUT;
770
1113
  return value;
771
1114
  }
1115
+ if (CLAUDE_SONNET_128K_OUTPUT_PATTERN.test(modelName)) {
1116
+ if (value > ANTHROPIC_MAX_OUTPUT) return ANTHROPIC_MAX_OUTPUT;
1117
+ return value;
1118
+ }
772
1119
  if (/claude-(?:sonnet|haiku)[-.]?[4-9]/.test(modelName) && value > CLAUDE_4_64K_MAX_OUTPUT) return CLAUDE_4_64K_MAX_OUTPUT;
773
1120
  if (/claude-opus[-.]?(?:[5-9]|4[-.]?([5-9]|\d{2,}))/.test(modelName)) {
774
1121
  if (value > CLAUDE_4_64K_MAX_OUTPUT) return CLAUDE_4_64K_MAX_OUTPUT;
@@ -878,12 +1225,21 @@ const tPluginSchema = z.object({
878
1225
  authenticated: z.boolean().optional(),
879
1226
  chatMenu: z.boolean().optional(),
880
1227
  isButton: z.boolean().optional(),
881
- toolkit: z.boolean().optional()
1228
+ toolkit: z.boolean().optional(),
1229
+ /** Raw upstream tool name when the model-facing key stripped a redundant
1230
+ * server-name prefix — proves upstream identity for legacy id migration. */
1231
+ serverToolName: z.string().optional()
882
1232
  });
883
1233
  const tExampleSchema = z.object({
884
1234
  input: z.object({ content: z.string() }),
885
1235
  output: z.object({ content: z.string() })
886
1236
  });
1237
+ /** Compact context-fading tier persisted beside a message's calibration ratio. */
1238
+ const agentFadingTierSchema = z.object({
1239
+ v: z.literal(1),
1240
+ budgetTokens: z.number().positive(),
1241
+ masked: z.boolean()
1242
+ });
887
1243
  const tMessageSchema = z.object({
888
1244
  messageId: z.string(),
889
1245
  endpoint: z.string().optional(),
@@ -900,6 +1256,12 @@ const tMessageSchema = z.object({
900
1256
  /** @deprecated */
901
1257
  generation: z.string().nullable().optional(),
902
1258
  isCreatedByUser: z.boolean(),
1259
+ /** True when the complete stored row came from outside the model. */
1260
+ isUserSubmitted: z.boolean().optional(),
1261
+ /** JSON pointers to caller-authored fields in an otherwise mixed model response. */
1262
+ userSubmittedPaths: z.array(z.string().startsWith("/")).optional(),
1263
+ /** Exact HITL message-field identity for caller-authored values stored in mixed responses. */
1264
+ userSubmittedMessageFieldPaths: z.array(userSubmittedMessageFieldPathSchema).optional(),
903
1265
  isTemporary: z.boolean().optional(),
904
1266
  expiredAt: z.string().nullable().optional(),
905
1267
  error: z.boolean().optional(),
@@ -919,7 +1281,9 @@ const tMessageSchema = z.object({
919
1281
  tokenCount: z.number().optional(),
920
1282
  contextMeta: z.object({
921
1283
  calibrationRatio: z.number().optional().describe("EMA ratio of provider-reported vs local token estimates; seeds the pruner on subsequent runs"),
922
- encoding: z.string().optional().describe("Tokenizer encoding used when this ratio was computed (e.g. \"claude\", \"o200k_base\")")
1284
+ encoding: z.string().optional().describe("Tokenizer encoding used when this ratio was computed (e.g. \"claude\", \"o200k_base\")"),
1285
+ fading: agentFadingTierSchema.optional().describe("Latched context-fading tier of the default agent; seeds the next run so the provider projection of history keeps the same bytes"),
1286
+ fadingTiers: z.array(agentFadingTierSchema.extend({ agentId: z.string().min(1) })).optional().describe("Latched context-fading tiers keyed by agent ID, stored as entries")
923
1287
  }).optional(),
924
1288
  /**
925
1289
  * Skill names the user invoked manually via the `$` popover on this turn.
@@ -947,6 +1311,29 @@ const tMessageSchema = z.object({
947
1311
  */
948
1312
  quotes: z.array(z.string()).optional()
949
1313
  });
1314
+ /**
1315
+ * Which memory partition an agent reads/writes.
1316
+ * `user` = the shared personal pool (default); `agent` = a partition
1317
+ * isolated per (user, agent) so the agent only sees its own memories.
1318
+ */
1319
+ let MemoryScope = /* @__PURE__ */ function(MemoryScope) {
1320
+ MemoryScope["user"] = "user";
1321
+ MemoryScope["agent"] = "agent";
1322
+ return MemoryScope;
1323
+ }({});
1324
+ /** Catalog exposure for a persisted agent with skills enabled. */
1325
+ let SkillsScope = /* @__PURE__ */ function(SkillsScope) {
1326
+ SkillsScope["all"] = "all";
1327
+ SkillsScope["selected"] = "selected";
1328
+ SkillsScope["none"] = "none";
1329
+ return SkillsScope;
1330
+ }({});
1331
+ /** Resolves explicit and legacy persisted-agent skill catalog states. */
1332
+ function resolveAgentSkillsScope(skills, enabled, scope) {
1333
+ if (enabled !== true) return "none";
1334
+ if (scope !== void 0) return scope;
1335
+ return (skills ?? []).length > 0 ? "selected" : "all";
1336
+ }
950
1337
  const coerceNumber = z.union([z.number(), z.string()]).transform((val) => {
951
1338
  if (typeof val === "string") return val.trim() === "" ? void 0 : parseFloat(val);
952
1339
  return val;
@@ -959,12 +1346,26 @@ const DocumentType = z.lazy(() => z.union([
959
1346
  z.array(z.lazy(() => DocumentType)),
960
1347
  z.record(z.lazy(() => DocumentType))
961
1348
  ]));
1349
+ const subagentThreadLineageSchema = z.object({
1350
+ rootConversationId: z.string().min(1),
1351
+ parentConversationId: z.string().min(1),
1352
+ parentMessageId: z.string().min(1),
1353
+ parentToolCallId: z.string().min(1),
1354
+ parentAgentId: z.string().min(1).optional(),
1355
+ subagentType: z.string().min(1),
1356
+ subagentKind: z.enum(["agent", "graph"]),
1357
+ depth: z.number().int().positive()
1358
+ });
962
1359
  const tConversationSchema = z.object({
963
1360
  conversationId: z.string().nullable(),
964
1361
  endpoint: eModelEndpointSchema.nullable(),
965
1362
  endpointType: eModelEndpointSchema.nullable().optional(),
966
1363
  isArchived: z.boolean().optional(),
1364
+ /** When the chat was archived; absent on chats archived before this was recorded. */
1365
+ archivedAt: z.string().nullable().optional(),
967
1366
  pinned: z.boolean().optional(),
1367
+ /** Server-derived: an active shared link exists for this conversation. Not persisted. */
1368
+ isShared: z.boolean().optional(),
968
1369
  title: z.string().nullable().or(z.literal("New Chat")).default("New Chat"),
969
1370
  user: z.string().optional(),
970
1371
  messages: z.array(z.string()).optional(),
@@ -1002,6 +1403,8 @@ const tConversationSchema = z.object({
1002
1403
  imageDetail: eImageDetailSchema.optional(),
1003
1404
  reasoning_effort: eReasoningEffortSchema.optional().nullable(),
1004
1405
  reasoning_summary: eReasoningSummarySchema.optional().nullable(),
1406
+ reasoning_mode: eReasoningModeSchema.optional().nullable(),
1407
+ reasoning_context: eReasoningContextSchema.optional().nullable(),
1005
1408
  verbosity: eVerbositySchema.optional().nullable(),
1006
1409
  useResponsesApi: z.boolean().optional(),
1007
1410
  effort: eAnthropicEffortSchema.optional().nullable(),
@@ -1011,6 +1414,8 @@ const tConversationSchema = z.object({
1011
1414
  disableStreaming: z.boolean().optional(),
1012
1415
  assistant_id: z.string().optional(),
1013
1416
  agent_id: z.string().optional(),
1417
+ /** Durable parent/child navigation for a subagent thread. */
1418
+ subagentThread: subagentThreadLineageSchema.optional(),
1014
1419
  region: z.string().optional(),
1015
1420
  maxTokens: coerceNumber.optional(),
1016
1421
  additionalModelRequestFields: DocumentType.optional(),
@@ -1093,6 +1498,10 @@ const tQueryParamsSchema = tConversationSchema.pick({
1093
1498
  /** @endpoints openAI, custom, azureOpenAI */
1094
1499
  reasoning_summary: true,
1095
1500
  /** @endpoints openAI, custom, azureOpenAI */
1501
+ reasoning_mode: true,
1502
+ /** @endpoints openAI, custom, azureOpenAI */
1503
+ reasoning_context: true,
1504
+ /** @endpoints openAI, custom, azureOpenAI */
1096
1505
  verbosity: true,
1097
1506
  /** @endpoints openAI, custom, azureOpenAI */
1098
1507
  useResponsesApi: true,
@@ -1162,6 +1571,26 @@ const tModelSpecPresetSchema = tPresetSchema.omit({
1162
1571
  chatGptLabel: true,
1163
1572
  presetOverride: true,
1164
1573
  spec: true
1574
+ }).merge(z.object({
1575
+ /**
1576
+ * Optional here, unlike `tPresetSchema`, where the key is required (though
1577
+ * nullable). A preset naming an `agent_id` has an unambiguous endpoint, so
1578
+ * config may omit it and `resolveModelSpecEndpoint` infers `agents` when
1579
+ * specs are materialized at config load.
1580
+ */
1581
+ endpoint: extendedModelEndpointSchema.nullish() })).superRefine((preset, ctx) => {
1582
+ /**
1583
+ * Omission is only legal when the endpoint is inferable, which requires a
1584
+ * NON-EMPTY `agent_id` — form-backed writers persist untouched fields as
1585
+ * `''`, which names no agent. An explicit `endpoint: null` stays accepted:
1586
+ * it validated before the key became optional, so rejecting it now would
1587
+ * break previously valid configs.
1588
+ */
1589
+ if (preset.endpoint === void 0 && !preset.agent_id) ctx.addIssue({
1590
+ code: z.ZodIssueCode.custom,
1591
+ path: ["endpoint"],
1592
+ message: "endpoint is required unless the preset names a non-empty agent_id (the agents endpoint is then inferred)"
1593
+ });
1165
1594
  });
1166
1595
  const tSharedLinkSchema = z.object({
1167
1596
  conversationId: z.string(),
@@ -1190,6 +1619,7 @@ const googleBaseSchema = tConversationSchema.pick({
1190
1619
  examples: true,
1191
1620
  temperature: true,
1192
1621
  maxOutputTokens: true,
1622
+ resendFiles: true,
1193
1623
  artifacts: true,
1194
1624
  topP: true,
1195
1625
  topK: true,
@@ -1348,6 +1778,8 @@ const openAIBaseSchema = tConversationSchema.pick({
1348
1778
  max_tokens: true,
1349
1779
  reasoning_effort: true,
1350
1780
  reasoning_summary: true,
1781
+ reasoning_mode: true,
1782
+ reasoning_context: true,
1351
1783
  verbosity: true,
1352
1784
  useResponsesApi: true,
1353
1785
  web_search: true,
@@ -1446,15 +1878,39 @@ const requiredSettingFields = [
1446
1878
  "type",
1447
1879
  "component"
1448
1880
  ];
1881
+ function clampSettingRange(value, range) {
1882
+ if (range.positiveMin != null) {
1883
+ /** The minimum carries its own meaning here (Google's -1 for automatic),
1884
+ * and the schema admits it outright, so it survives rather than being
1885
+ * lifted to the floor. It need not be negative to be the sentinel. */
1886
+ if (value === range.min) return range.min;
1887
+ /** Below the sentinel there is nothing admissible to lift to, so the value
1888
+ * resolves to it. Between the sentinel and the floor, the floor is the
1889
+ * nearest value the generated schema accepts. */
1890
+ if (value < Math.max(range.min, 0)) return range.min;
1891
+ return Math.min(Math.max(value, range.positiveMin), range.max);
1892
+ }
1893
+ return Math.min(Math.max(value, range.min), range.max);
1894
+ }
1449
1895
  function generateDynamicSchema(settings) {
1450
1896
  const schemaFields = {};
1451
1897
  for (const setting of settings) {
1452
1898
  const { key, type, default: defaultValue, range, options, minText, maxText, minTags, maxTags } = setting;
1453
1899
  if (type === "number") {
1454
- let schema = z.number();
1900
+ let numberSchema = z.number();
1455
1901
  if (range) {
1456
- schema = schema.min(range.min);
1457
- schema = schema.max(range.max);
1902
+ numberSchema = numberSchema.min(range.min);
1903
+ numberSchema = numberSchema.max(range.max);
1904
+ }
1905
+ /** Widened deliberately: refine returns ZodEffects, not ZodNumber, and
1906
+ * the number-specific chaining is already done above. */
1907
+ let schema = numberSchema;
1908
+ if (range?.positiveMin != null) {
1909
+ /** Mirrors clampSettingRange so the generated schema and the clamp
1910
+ * agree: `min` only admits the sentinel, and any non-negative value
1911
+ * must clear the documented floor. */
1912
+ const { positiveMin, min } = range;
1913
+ schema = numberSchema.refine((value) => value === min || value >= positiveMin, `Expected ${min} or a value of at least ${positiveMin}`);
1458
1914
  }
1459
1915
  if (typeof defaultValue === "number") schemaFields[key] = schema.default(defaultValue);
1460
1916
  else schemaFields[key] = schema;
@@ -1596,7 +2052,14 @@ function validateSettingDefinitions(settings) {
1596
2052
  setting.includeInput = setting.type === "number" ? setting.includeInput ?? true : false;
1597
2053
  }
1598
2054
  if (setting.component === "slider" && setting.type === "number") {
1599
- if (setting.default === void 0 && setting.range) setting.default = Math.round((setting.range.min + setting.range.max) / 2);
2055
+ if (setting.default === void 0 && setting.range) {
2056
+ /** The midpoint of the admissible interval, which a positive floor
2057
+ * narrows: the span between the sentinel and that floor holds no value
2058
+ * the generated schema accepts, so a midpoint taken across it would
2059
+ * fail the validation below. */
2060
+ const floor = Math.max(setting.range.min, setting.range.positiveMin ?? setting.range.min);
2061
+ setting.default = Math.round((floor + setting.range.max) / 2);
2062
+ }
1600
2063
  }
1601
2064
  if (setting.component === "checkbox" || setting.component === "switch") {
1602
2065
  if (setting.options && setting.options.length > 2) errors.push({
@@ -1674,6 +2137,16 @@ function validateSettingDefinitions(settings) {
1674
2137
  message: `Invalid default value for setting ${setting.key}. Must be within the range [${setting.range.min}, ${setting.range.max}].`,
1675
2138
  path: ["default"]
1676
2139
  });
2140
+ if (setting.type === "number" && setting.range?.positiveMin != null && setting.range.positiveMin > setting.range.max) errors.push({
2141
+ code: ZodIssueCode.custom,
2142
+ message: `Invalid range for setting ${setting.key}. positiveMin (${setting.range.positiveMin}) cannot exceed max (${setting.range.max}).`,
2143
+ path: ["range"]
2144
+ });
2145
+ if (setting.type === "number" && setting.range?.positiveMin != null && typeof setting.default === "number" && setting.default !== setting.range.min && setting.default < setting.range.positiveMin) errors.push({
2146
+ code: ZodIssueCode.custom,
2147
+ message: `Invalid default value for setting ${setting.key}. Must be ${setting.range.min} or at least ${setting.range.positiveMin}.`,
2148
+ path: ["default"]
2149
+ });
1677
2150
  if (setting.enumMappings && setting.type === "enum" && setting.options) {
1678
2151
  for (const option of setting.options) if (!(option in setting.enumMappings)) errors.push({
1679
2152
  code: ZodIssueCode.custom,
@@ -1775,13 +2248,83 @@ const generateGoogleSchema = (customGoogle) => {
1775
2248
  //#region src/limits.ts
1776
2249
  /** Maximum number of explicit subagents per parent agent. UI + Zod schema share this. */
1777
2250
  const MAX_SUBAGENTS = 10;
2251
+ /** Hard upper bound for `endpoints.agents.maxSubagents`, keeping the request-validation
2252
+ * cap bounded no matter what the config file says. */
2253
+ const MAX_SUBAGENTS_CEILING = 50;
2254
+ let maxSubagents = 10;
2255
+ /** Effective subagents-per-agent cap; initialized from `endpoints.agents.maxSubagents` at startup. */
2256
+ const getMaxSubagents = () => maxSubagents;
2257
+ /** Applies a configured cap; any missing or out-of-range value resets to the default. */
2258
+ const setMaxSubagents = (value) => {
2259
+ maxSubagents = typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= 50 ? value : 10;
2260
+ };
2261
+ /** Chat project field limits. The dialogs and the persistence layer share these,
2262
+ * so the inputs stop at the same point the server would otherwise truncate. */
2263
+ const MAX_CHAT_PROJECT_NAME_LENGTH = 100;
2264
+ const MAX_CHAT_PROJECT_DESCRIPTION_LENGTH = 1e3;
2265
+ /** Mirrors the bounded graph-child member limit in `@librechat/agents`. */
2266
+ const MAX_GRAPH_SUBAGENT_MEMBERS = 32;
1778
2267
  //#endregion
1779
2268
  //#region src/models.ts
1780
2269
  const modelSpecSubagentsSchema = z.object({
1781
2270
  enabled: z.boolean().optional(),
1782
2271
  allowSelf: z.boolean().optional(),
1783
- agent_ids: z.array(z.string()).max(10).optional()
2272
+ agent_ids: z.array(z.string()).optional()
2273
+ }).superRefine((subagents, ctx) => {
2274
+ const maxSubagents = getMaxSubagents();
2275
+ if ((subagents.agent_ids?.length ?? 0) > maxSubagents) ctx.addIssue({
2276
+ code: z.ZodIssueCode.custom,
2277
+ path: ["agent_ids"],
2278
+ message: `agent_ids must contain at most ${maxSubagents} item(s)`
2279
+ });
1784
2280
  });
2281
+ function resolveModelSpecEndpoint(modelSpec) {
2282
+ const preset = modelSpec?.preset;
2283
+ if (preset?.endpoint != null) return preset.endpoint;
2284
+ /**
2285
+ * An explicit `endpoint: null` is a statement, not an omission — such specs
2286
+ * validated (and were skipped downstream) before inference existed, so
2287
+ * inferring here would silently activate them. Only an absent key infers,
2288
+ * and only from a non-empty `agent_id`: form-backed writers persist
2289
+ * untouched fields as `''`, which names no agent.
2290
+ */
2291
+ if (preset?.endpoint === null) return;
2292
+ return preset?.agent_id ? "agents" : void 0;
2293
+ }
2294
+ /**
2295
+ * Writes each spec's resolved endpoint back onto its preset so every consumer —
2296
+ * endpoint matching, the selector, access filters, startup presets, provider-key
2297
+ * reachability — reads a complete spec instead of re-deriving it. Apply once
2298
+ * where the effective config is assembled (YAML load and DB-override merge);
2299
+ * downstream code then needs no awareness of inference.
2300
+ *
2301
+ * Returns the original object, and the original spec objects, when nothing
2302
+ * needs filling in, so cached configs and memoized consumers see no new
2303
+ * identities.
2304
+ */
2305
+ function materializeModelSpecEndpoints(modelSpecs) {
2306
+ const list = modelSpecs?.list;
2307
+ if (!list?.length) return modelSpecs;
2308
+ let changed = false;
2309
+ const materialized = list.map((spec) => {
2310
+ if (spec?.preset == null || spec.preset.endpoint != null) return spec;
2311
+ const endpoint = resolveModelSpecEndpoint(spec);
2312
+ if (endpoint == null) return spec;
2313
+ changed = true;
2314
+ return {
2315
+ ...spec,
2316
+ preset: {
2317
+ ...spec.preset,
2318
+ endpoint
2319
+ }
2320
+ };
2321
+ });
2322
+ if (!changed) return modelSpecs;
2323
+ return {
2324
+ ...modelSpecs,
2325
+ list: materialized
2326
+ };
2327
+ }
1785
2328
  const tModelSpecSchema = z.object({
1786
2329
  name: z.string(),
1787
2330
  label: z.string(),
@@ -1796,12 +2339,17 @@ const tModelSpecSchema = z.object({
1796
2339
  showIconInHeader: z.boolean().optional(),
1797
2340
  showOnLanding: z.boolean().optional(),
1798
2341
  conversation_starters: z.array(z.string()).optional(),
2342
+ showInMenu: z.boolean().optional(),
1799
2343
  iconURL: z.union([z.string(), eModelEndpointSchema]).optional(),
1800
2344
  authType: authTypeSchema.optional(),
1801
2345
  hideBadgeRow: z.boolean().optional(),
1802
2346
  webSearch: z.boolean().optional(),
1803
2347
  fileSearch: z.boolean().optional(),
1804
2348
  executeCode: z.boolean().optional(),
2349
+ memory: z.boolean().optional(),
2350
+ askUserQuestion: z.boolean().optional(),
2351
+ runInBackground: z.union([z.boolean(), z.array(z.string())]).optional(),
2352
+ describeIntent: z.union([z.boolean(), z.array(z.string())]).optional(),
1805
2353
  artifacts: z.union([z.string(), z.boolean()]).optional(),
1806
2354
  mcpServers: z.array(z.string()).optional(),
1807
2355
  skills: z.union([z.boolean(), z.array(z.string())]).optional(),
@@ -1883,6 +2431,7 @@ const fullMimeTypesList = [
1883
2431
  "application/pdf",
1884
2432
  "text/x-php",
1885
2433
  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
2434
+ "application/vnd.openxmlformats-officedocument.presentationml.template",
1886
2435
  "text/x-python",
1887
2436
  "text/x-script.python",
1888
2437
  "text/x-ruby",
@@ -1913,6 +2462,7 @@ const fullMimeTypesList = [
1913
2462
  "application/vnd.oasis.opendocument.graphics",
1914
2463
  "image/svg",
1915
2464
  "image/svg+xml",
2465
+ "message/rfc822",
1916
2466
  "video/mp4",
1917
2467
  "video/avi",
1918
2468
  "video/mov",
@@ -1946,6 +2496,7 @@ const codeInterpreterMimeTypesList = [
1946
2496
  "application/pdf",
1947
2497
  "text/x-php",
1948
2498
  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
2499
+ "application/vnd.openxmlformats-officedocument.presentationml.template",
1949
2500
  "text/x-python",
1950
2501
  "text/x-script.python",
1951
2502
  "text/x-ruby",
@@ -1978,6 +2529,7 @@ const retrievalMimeTypesList = [
1978
2529
  "application/pdf",
1979
2530
  "text/x-php",
1980
2531
  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
2532
+ "application/vnd.openxmlformats-officedocument.presentationml.template",
1981
2533
  "text/x-python",
1982
2534
  "text/x-script.python",
1983
2535
  "text/x-ruby",
@@ -1999,11 +2551,34 @@ const bedrockDocumentFormats = {
1999
2551
  "text/markdown": "md"
2000
2552
  };
2001
2553
  const isBedrockDocumentType = (mimeType) => mimeType != null && mimeType in bedrockDocumentFormats;
2554
+ /** MIME types Bedrock's Converse document path can send to the model (mirrors `bedrockDocumentFormats`). */
2555
+ const bedrockDocumentMimeTypes = Object.keys(bedrockDocumentFormats);
2002
2556
  /** File extensions accepted by Bedrock document uploads (for input accept attributes) */
2003
2557
  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";
2558
+ /** Textual `application/*` MIME types that can be decoded and sent as plain text */
2559
+ const textualApplicationTypes = new Set([
2560
+ "application/json",
2561
+ "application/xml",
2562
+ "application/yaml",
2563
+ "application/sql",
2564
+ "application/typescript",
2565
+ "application/x-sh",
2566
+ "application/csv"
2567
+ ]);
2568
+ /**
2569
+ * MIME types the Anthropic Messages API accepts as a plain-text document source
2570
+ * (`source.type: 'text'`)
2571
+ */
2572
+ const isAnthropicTextDocumentType = (mimeType) => mimeType != null && (mimeType.startsWith("text/") || textualApplicationTypes.has(mimeType));
2573
+ /**
2574
+ * MIME types the Anthropic Messages API document path can send to the model
2575
+ * (mirrors `isBedrockDocumentType`): PDF via base64, textual types via a
2576
+ * plain-text document source. All other types are rejected with a provider 400.
2577
+ */
2578
+ const isAnthropicDocumentType = (mimeType) => mimeType === "application/pdf" || isAnthropicTextDocumentType(mimeType);
2004
2579
  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)$/;
2005
2580
  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))$/;
2006
- 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))$/;
2581
+ 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))$/;
2007
2582
  const imageMimeTypes = /^image\/(jpeg|gif|png|webp|heic|heif)$/;
2008
2583
  const audioMimeTypes = /^audio\/(mp3|mpeg|mpeg3|wav|wave|x-wav|ogg|vorbis|mp4|m4a|x-m4a|flac|x-flac|webm|aac|wma|opus)$/;
2009
2584
  const videoMimeTypes = /^video\/(mp4|avi|mov|wmv|flv|webm|mkv|m4v|3gp|ogv)$/;
@@ -2012,6 +2587,7 @@ const defaultOCRMimeTypes = [
2012
2587
  excelMimeTypes,
2013
2588
  /^application\/pdf$/,
2014
2589
  /^application\/vnd\.openxmlformats-officedocument\.(wordprocessingml\.document|presentationml\.presentation)$/,
2590
+ /^application\/vnd\.openxmlformats-officedocument\.presentationml\.template$/,
2015
2591
  /^application\/vnd\.ms-(word|powerpoint)$/,
2016
2592
  /^application\/epub\+zip$/,
2017
2593
  /^application\/vnd\.oasis\.opendocument\.(text|spreadsheet|presentation|graphics)$/
@@ -2033,7 +2609,8 @@ const supportedMimeTypes = [
2033
2609
  imageMimeTypes,
2034
2610
  videoMimeTypes,
2035
2611
  audioMimeTypes,
2036
- /^image\/(svg|svg\+xml)$/
2612
+ /^image\/(svg|svg\+xml)$/,
2613
+ /^message\/rfc822$/
2037
2614
  ];
2038
2615
  const codeInterpreterMimeTypes = [
2039
2616
  textMimeTypes,
@@ -2088,6 +2665,7 @@ const codeTypeMapping = {
2088
2665
  cljs: "text/plain",
2089
2666
  cljc: "text/plain",
2090
2667
  elm: "text/plain",
2668
+ eml: "message/rfc822",
2091
2669
  erl: "text/plain",
2092
2670
  hrl: "text/plain",
2093
2671
  ex: "text/plain",
@@ -2159,6 +2737,13 @@ const codeTypeMapping = {
2159
2737
  ods: "application/vnd.oasis.opendocument.spreadsheet",
2160
2738
  odp: "application/vnd.oasis.opendocument.presentation",
2161
2739
  odg: "application/vnd.oasis.opendocument.graphics",
2740
+ doc: "application/msword",
2741
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
2742
+ xls: "application/vnd.ms-excel",
2743
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
2744
+ ppt: "application/vnd.ms-powerpoint",
2745
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
2746
+ potx: "application/vnd.openxmlformats-officedocument.presentationml.template",
2162
2747
  ics: "text/calendar",
2163
2748
  ical: "text/calendar",
2164
2749
  ifb: "text/calendar",
@@ -2173,7 +2758,11 @@ const imageTypeMapping = {
2173
2758
  const mimeTypeAliases = {
2174
2759
  "application/x-zip-compressed": "application/zip",
2175
2760
  "text/x-python-script": "text/x-python",
2176
- "text/x-markdown": "text/markdown"
2761
+ "text/x-markdown": "text/markdown",
2762
+ /** freedesktop shared-mime-info (Chrome on Linux) */
2763
+ "application/x-shellscript": "application/x-sh",
2764
+ /** libmagic, i.e. `file --mime-type` */
2765
+ "text/x-shellscript": "application/x-sh"
2177
2766
  };
2178
2767
  /**
2179
2768
  * Infers the MIME type from a file's extension when the browser doesn't recognize it,
@@ -2187,7 +2776,7 @@ function inferMimeType(fileName, currentType) {
2187
2776
  const extension = fileName.split(".").pop()?.toLowerCase() ?? "";
2188
2777
  return codeTypeMapping[extension] || imageTypeMapping[extension] || currentType;
2189
2778
  }
2190
- 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)))$/];
2779
+ 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))))$/];
2191
2780
  const megabyte = 1024 * 1024;
2192
2781
  /** Helper function to get megabytes value */
2193
2782
  const mbToBytes = (mb) => mb * megabyte;
@@ -2229,7 +2818,8 @@ const fileConfig = {
2229
2818
  enabled: false,
2230
2819
  maxWidth: 1900,
2231
2820
  maxHeight: 1900,
2232
- quality: .92
2821
+ quality: .92,
2822
+ enforced: false
2233
2823
  },
2234
2824
  ocr: { supportedMimeTypes: defaultOCRMimeTypes },
2235
2825
  text: { supportedMimeTypes: defaultTextMimeTypes },
@@ -2259,28 +2849,219 @@ const fileConfigSchema = z.object({
2259
2849
  }).optional(),
2260
2850
  clientImageResize: z.object({
2261
2851
  enabled: z.boolean().optional(),
2262
- maxWidth: z.number().min(0).optional(),
2263
- maxHeight: z.number().min(0).optional(),
2852
+ maxWidth: z.number().min(1).optional(),
2853
+ maxHeight: z.number().min(1).optional(),
2264
2854
  quality: z.number().min(0).max(1).optional()
2265
2855
  }).optional(),
2266
2856
  ocr: z.object({ supportedMimeTypes: supportedMimeTypesSchema.optional() }).optional(),
2267
2857
  text: z.object({ supportedMimeTypes: supportedMimeTypesSchema.optional() }).optional()
2268
2858
  });
2269
- /** Helper function to safely convert string patterns to RegExp objects */
2270
- const convertStringsToRegex = (patterns) => patterns.reduce((acc, pattern) => {
2271
- try {
2272
- const regex = new RegExp(pattern);
2273
- acc.push(regex);
2274
- } catch (error) {
2275
- console.error(`Invalid regex pattern "${pattern}" skipped.`, error);
2859
+ /**
2860
+ * Compiler for admin-supplied MIME patterns. Defaults to native `RegExp`, which browser
2861
+ * builds keep so no extra dependency is bundled. The server swaps in a linear-time engine
2862
+ * via `setFileConfigRegexCompiler` so an admin-authored catastrophic-backtracking pattern
2863
+ * cannot ReDoS the shared event loop when tested against an uploaded file's MIME type.
2864
+ */
2865
+ let compileMimeRegex = (pattern) => new RegExp(pattern);
2866
+ /** Override the MIME-pattern compiler; the server injects a linear-time engine at startup. */
2867
+ const setFileConfigRegexCompiler = (compile) => {
2868
+ compileMimeRegex = compile;
2869
+ };
2870
+ /** Returned when every configured pattern fails to compile, so consumers that read an empty
2871
+ * allowlist as "no restriction" fail closed instead of allowing every file. */
2872
+ const rejectAllMimeMatcher = { test: () => false };
2873
+ /** Helper function to safely convert string patterns to matcher objects */
2874
+ const convertStringsToRegex = (patterns) => {
2875
+ const compiled = patterns.reduce((acc, pattern) => {
2876
+ try {
2877
+ acc.push(compileMimeRegex(pattern));
2878
+ } catch (error) {
2879
+ console.error(`Invalid regex pattern "${pattern}" skipped.`, error);
2880
+ }
2881
+ return acc;
2882
+ }, []);
2883
+ if (patterns.length > 0 && compiled.length === 0) {
2884
+ console.error(`All ${patterns.length} MIME type pattern(s) were invalid and skipped; the resulting allowlist rejects every file.`);
2885
+ return [rejectAllMimeMatcher];
2276
2886
  }
2277
- return acc;
2278
- }, []);
2887
+ return compiled;
2888
+ };
2279
2889
  /** Detects whether the given MIME type patterns accept all file types (e.g., `.*` or `.+`). */
2280
2890
  const isPermissiveMimeConfig = (types) => {
2281
2891
  if (!types || types.length === 0) return false;
2282
2892
  return types.some((regex) => regex.test("x-librechat/x-probe"));
2283
2893
  };
2894
+ /** Media categories that collapse to a wildcard `accept` token when any member type is allowed. */
2895
+ const mimeAcceptCategories = [
2896
+ {
2897
+ /** Mirrors `imageMimeTypes` (+ the code-interpreter svg variants) so every accepted type is known. */
2898
+ category: "image",
2899
+ token: "image/*",
2900
+ samples: [
2901
+ "image/jpeg",
2902
+ "image/gif",
2903
+ "image/png",
2904
+ "image/webp",
2905
+ "image/heic",
2906
+ "image/heif",
2907
+ "image/svg",
2908
+ "image/svg+xml"
2909
+ ],
2910
+ extras: [".heif", ".heic"]
2911
+ },
2912
+ {
2913
+ /** Mirrors `audioMimeTypes`. */
2914
+ category: "audio",
2915
+ token: "audio/*",
2916
+ samples: [
2917
+ "audio/mp3",
2918
+ "audio/mpeg",
2919
+ "audio/mpeg3",
2920
+ "audio/wav",
2921
+ "audio/wave",
2922
+ "audio/x-wav",
2923
+ "audio/ogg",
2924
+ "audio/vorbis",
2925
+ "audio/mp4",
2926
+ "audio/m4a",
2927
+ "audio/x-m4a",
2928
+ "audio/flac",
2929
+ "audio/x-flac",
2930
+ "audio/webm",
2931
+ "audio/aac",
2932
+ "audio/wma",
2933
+ "audio/opus"
2934
+ ]
2935
+ },
2936
+ {
2937
+ /** Mirrors `videoMimeTypes`. */
2938
+ category: "video",
2939
+ token: "video/*",
2940
+ samples: [
2941
+ "video/mp4",
2942
+ "video/avi",
2943
+ "video/mov",
2944
+ "video/wmv",
2945
+ "video/flv",
2946
+ "video/webm",
2947
+ "video/mkv",
2948
+ "video/m4v",
2949
+ "video/3gp",
2950
+ "video/ogv"
2951
+ ]
2952
+ }
2953
+ ];
2954
+ /** Document/text MIME types paired with the extension(s) browsers filter on in the file picker. */
2955
+ const documentMimeExtensions = [
2956
+ ["application/pdf", [".pdf"]],
2957
+ ["application/msword", [".doc"]],
2958
+ ["application/vnd.openxmlformats-officedocument.wordprocessingml.document", [".docx"]],
2959
+ ["application/vnd.ms-excel", [".xls"]],
2960
+ ["application/msexcel", [".xls"]],
2961
+ ["application/x-msexcel", [".xls"]],
2962
+ ["application/x-ms-excel", [".xls"]],
2963
+ ["application/x-excel", [".xls"]],
2964
+ ["application/x-dos_ms_excel", [".xls"]],
2965
+ ["application/xls", [".xls"]],
2966
+ ["application/x-xls", [".xls"]],
2967
+ ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", [".xlsx"]],
2968
+ ["application/vnd.ms-powerpoint", [".ppt"]],
2969
+ ["application/vnd.openxmlformats-officedocument.presentationml.presentation", [".pptx"]],
2970
+ ["application/vnd.openxmlformats-officedocument.presentationml.template", [".potx"]],
2971
+ ["application/vnd.oasis.opendocument.text", [".odt"]],
2972
+ ["application/vnd.oasis.opendocument.spreadsheet", [".ods"]],
2973
+ ["application/vnd.oasis.opendocument.presentation", [".odp"]],
2974
+ ["application/vnd.oasis.opendocument.graphics", [".odg"]],
2975
+ ["application/rtf", [".rtf"]],
2976
+ ["application/json", [".json"]],
2977
+ ["application/xml", [".xml"]],
2978
+ ["application/yaml", [".yaml", ".yml"]],
2979
+ ["application/zip", [".zip"]],
2980
+ ["application/x-zip-compressed", [".zip"]],
2981
+ ["application/epub+zip", [".epub"]],
2982
+ ["application/x-parquet", [".parquet"]],
2983
+ ["application/vnd.apache.parquet", [".parquet"]],
2984
+ ["text/csv", [".csv"]],
2985
+ ["application/csv", [".csv"]],
2986
+ ["text/tab-separated-values", [".tsv"]],
2987
+ ["text/plain", [".txt"]],
2988
+ ["text/markdown", [".md"]],
2989
+ ["text/html", [".html", ".htm"]],
2990
+ ["text/calendar", [".ics"]],
2991
+ ["message/rfc822", [".eml"]]
2992
+ ];
2993
+ const documentMimeSet = new Set(documentMimeExtensions.map(([mimeType]) => mimeType));
2994
+ /** Every MIME type LibreChat may accept, used to detect patterns that reach beyond the representable set. */
2995
+ const knownMimeUniverse = Array.from(new Set([
2996
+ ...fullMimeTypesList,
2997
+ ...documentMimeExtensions.map(([mimeType]) => mimeType),
2998
+ ...mimeAcceptCategories.flatMap((category) => category.samples)
2999
+ ]));
3000
+ const categoryOf = (mimeType) => {
3001
+ if (mimeType.startsWith("image/")) return "image";
3002
+ if (mimeType.startsWith("audio/")) return "audio";
3003
+ if (mimeType.startsWith("video/")) return "video";
3004
+ return "document";
3005
+ };
3006
+ /** Media types are covered by their `<cat>/*` wildcard token; document types need an explicit entry. */
3007
+ const isRepresentable = (mimeType) => categoryOf(mimeType) !== "document" || documentMimeSet.has(mimeType);
3008
+ /**
3009
+ * Translates a finite MIME allowlist into a file-input `accept` string, intersected with what the
3010
+ * provider upload path can actually send. Returns `undefined` (keep the provider filter) when a
3011
+ * configured pattern matches a supported, path-handleable type that cannot be represented, so the
3012
+ * picker never hides a file the path would have accepted.
3013
+ */
3014
+ const buildMimeAccept = (types, { categories, documentMimeTypes }) => {
3015
+ const permittedSet = new Set(categories);
3016
+ const documentAllowSet = documentMimeTypes ? new Set(documentMimeTypes) : null;
3017
+ const emittedMedia = /* @__PURE__ */ new Set();
3018
+ const emittedDocuments = /* @__PURE__ */ new Set();
3019
+ if (!types.every((regex) => knownMimeUniverse.some((mimeType) => regex.test(mimeType)))) return;
3020
+ for (const regex of types) for (const mimeType of knownMimeUniverse) {
3021
+ if (!regex.test(mimeType)) continue;
3022
+ const category = categoryOf(mimeType);
3023
+ if (!permittedSet.has(category)) continue;
3024
+ /** The path handles documents but drops this specific type (e.g. Bedrock ignores pptx/ODF). */
3025
+ if (category === "document" && documentAllowSet && !documentAllowSet.has(mimeType)) continue;
3026
+ if (!isRepresentable(mimeType)) return;
3027
+ if (category === "document") emittedDocuments.add(mimeType);
3028
+ else emittedMedia.add(category);
3029
+ }
3030
+ const tokens = [];
3031
+ const seen = /* @__PURE__ */ new Set();
3032
+ const push = (token) => {
3033
+ if (!seen.has(token)) {
3034
+ seen.add(token);
3035
+ tokens.push(token);
3036
+ }
3037
+ };
3038
+ for (const category of mimeAcceptCategories) if (emittedMedia.has(category.category)) {
3039
+ push(category.token);
3040
+ category.extras?.forEach(push);
3041
+ }
3042
+ for (const [mimeType, extensions] of documentMimeExtensions) if (emittedDocuments.has(mimeType)) {
3043
+ extensions.forEach(push);
3044
+ push(mimeType);
3045
+ }
3046
+ return tokens.length > 0 ? tokens.join(",") : void 0;
3047
+ };
3048
+ /**
3049
+ * Resolves the file-input `accept` value for a configured `supportedMimeTypes` allowlist, scoped to
3050
+ * what the current upload path (`capability`) can send to the model.
3051
+ * - `undefined` for the built-in default or a config that can't be represented safely, so callers
3052
+ * keep their provider-specific filter.
3053
+ * - `''` for permissive configs (e.g. `.*`), leaving the picker unrestricted.
3054
+ * - a translated `accept` string for a recognized finite allowlist (images, PDFs, Office docs, etc.).
3055
+ *
3056
+ * The picker `accept` is a UX convenience, not a security boundary: the backend still enforces
3057
+ * `supportedMimeTypes` on upload.
3058
+ */
3059
+ const getConfiguredMimeAccept = (types, capability) => {
3060
+ /** Referential identity with the built-in list signals an unconfigured endpoint (keep provider filter). */
3061
+ if (!types || types.length === 0 || types === supportedMimeTypes) return;
3062
+ if (isPermissiveMimeConfig(types)) return "";
3063
+ return buildMimeAccept(types, capability);
3064
+ };
2284
3065
  /**
2285
3066
  * Gets the appropriate endpoint file configuration with standardized lookup logic.
2286
3067
  *
@@ -2375,7 +3156,8 @@ function mergeFileConfig(dynamic) {
2375
3156
  };
2376
3157
  if (dynamic.clientImageResize !== void 0) mergedConfig.clientImageResize = {
2377
3158
  ...mergedConfig.clientImageResize,
2378
- ...dynamic.clientImageResize
3159
+ ...dynamic.clientImageResize,
3160
+ enforced: dynamic.clientImageResize.enabled !== void 0
2379
3161
  };
2380
3162
  if (dynamic.ocr !== void 0) {
2381
3163
  const { supportedMimeTypes: ocrMimeTypes, ...ocrRest } = dynamic.ocr;
@@ -2436,9 +3218,14 @@ const buildQuery = (params) => {
2436
3218
  };
2437
3219
  const health = () => `${BASE_URL}/health`;
2438
3220
  const user = () => `${BASE_URL}/api/user`;
3221
+ const userPreferences = () => `${user()}/preferences`;
2439
3222
  const balance = () => `${BASE_URL}/api/balance`;
2440
3223
  const userPlugins = () => `${BASE_URL}/api/user/plugins`;
2441
3224
  const deleteUser$1 = () => `${BASE_URL}/api/user/delete`;
3225
+ const codeEnvironments = () => `${BASE_URL}/api/code-environments`;
3226
+ const codeEnvironmentPairings = () => `${codeEnvironments()}/pairings`;
3227
+ const codeEnvironmentById = (id) => `${codeEnvironments()}/${encodeURIComponent(id)}`;
3228
+ const codeEnvironmentSettings = (id) => `${codeEnvironmentById(id)}/settings`;
2442
3229
  const messagesRoot = `${BASE_URL}/api/messages`;
2443
3230
  const messages = (params) => {
2444
3231
  const { conversationId, messageId, ...rest } = params;
@@ -2450,9 +3237,16 @@ const messagesArtifacts = (messageId) => `${messagesRoot}/artifact/${messageId}`
2450
3237
  const messagesBranch = () => `${messagesRoot}/branch`;
2451
3238
  const shareRoot = `${BASE_URL}/api/share`;
2452
3239
  const shareMessages = (shareId) => `${shareRoot}/${shareId}`;
3240
+ const forkSharedMessages = (shareId) => `${shareRoot}/${shareId}/fork`;
2453
3241
  const sharedStartupConfig = (shareId) => `${shareMessages(shareId)}/config`;
2454
3242
  const getSharedLink$1 = (conversationId) => `${shareRoot}/link/${conversationId}`;
2455
- const getSharedLinks = (pageSize, sortBy, sortDirection, search, cursor) => `${shareRoot}?pageSize=${pageSize}&sortBy=${sortBy}&sortDirection=${sortDirection}${search ? `&search=${search}` : ""}${cursor ? `&cursor=${cursor}` : ""}`;
3243
+ const getSharedLinks = (pageSize, sortBy, sortDirection, search, cursor) => `${shareRoot}${buildQuery({
3244
+ pageSize,
3245
+ sortBy,
3246
+ sortDirection,
3247
+ search,
3248
+ cursor
3249
+ })}`;
2456
3250
  const createSharedLink$1 = (conversationId) => `${shareRoot}/${conversationId}`;
2457
3251
  const updateSharedLink$1 = (shareId) => `${shareRoot}/${shareId}`;
2458
3252
  /** Share-scoped file routes: serve snapshotted files via shared-link permission. */
@@ -2472,9 +3266,17 @@ const conversations = (params) => {
2472
3266
  return `${conversationsRoot}${buildQuery(params)}`;
2473
3267
  };
2474
3268
  const conversationById = (id) => `${conversationsRoot}/${id}`;
3269
+ const parentSubagents = (parentConversationId) => `${conversationsRoot}/${encodeURIComponent(parentConversationId)}/subagents`;
3270
+ const subagentThread = (parentConversationId, threadId, taskId, cursor) => {
3271
+ const endpoint = `${conversationsRoot}/${encodeURIComponent(parentConversationId)}/subagents/${encodeURIComponent(threadId)}`;
3272
+ if (taskId != null) return `${endpoint}?taskId=${encodeURIComponent(taskId)}`;
3273
+ return cursor == null ? endpoint : `${endpoint}?cursor=${encodeURIComponent(cursor)}`;
3274
+ };
3275
+ const subagentControl = (parentConversationId, threadId) => `${conversationsRoot}/${encodeURIComponent(parentConversationId)}/subagents/${encodeURIComponent(threadId)}/control`;
2475
3276
  const genTitle$1 = (conversationId) => `${conversationsRoot}/gen_title/${encodeURIComponent(conversationId)}`;
2476
3277
  const updateConversation$1 = () => `${conversationsRoot}/update`;
2477
3278
  const archiveConversation$1 = () => `${conversationsRoot}/archive`;
3279
+ const archiveAllConversations$1 = () => `${conversationsRoot}/archive/all`;
2478
3280
  const pinConversation$1 = () => `${conversationsRoot}/pin`;
2479
3281
  const deleteConversation$1 = () => `${conversationsRoot}`;
2480
3282
  const deleteAllConversation = () => `${conversationsRoot}/all`;
@@ -2492,7 +3294,6 @@ const presets = () => `${BASE_URL}/api/presets`;
2492
3294
  const deletePreset$1 = () => `${BASE_URL}/api/presets/delete`;
2493
3295
  const aiEndpoints = () => `${BASE_URL}/api/endpoints`;
2494
3296
  const tokenConfig = () => `${BASE_URL}/api/endpoints/token-config`;
2495
- const contextProjection = () => `${BASE_URL}/api/endpoints/context-projection`;
2496
3297
  const models = () => `${BASE_URL}/api/models`;
2497
3298
  const tokenizer = () => `${BASE_URL}/api/tokenizer`;
2498
3299
  const login$1 = () => `${BASE_URL}/api/auth/login`;
@@ -2531,6 +3332,7 @@ const mcpAuthValues = (serverName) => {
2531
3332
  const cancelMCPOAuth$1 = (serverName) => {
2532
3333
  return `${BASE_URL}/api/mcp/oauth/cancel/${serverName}`;
2533
3334
  };
3335
+ const mcpOAuthStatus = (flowId) => `${BASE_URL}/api/mcp/oauth/status/${encodeURIComponent(flowId)}`;
2534
3336
  const mcpOAuthBind = (serverName) => `${BASE_URL}/api/mcp/${serverName}/oauth/bind`;
2535
3337
  const actionOAuthBind = (actionId) => `${BASE_URL}/api/actions/${actionId}/oauth/bind`;
2536
3338
  const config = (context) => `${BASE_URL}/api/config${buildQuery({ context })}`;
@@ -2559,6 +3361,14 @@ const agents = ({ path = "", options }) => {
2559
3361
  return url;
2560
3362
  };
2561
3363
  const activeJobs = () => `${BASE_URL}/api/agents/chat/active`;
3364
+ const agentQueuedTurnsRoot = `${BASE_URL}/api/agents/chat/queued-turns`;
3365
+ const agentQueuedTurns = () => agentQueuedTurnsRoot;
3366
+ const agentQueuedTurnsByConversation = (conversationId, clientRequestIds = []) => {
3367
+ const uniqueIds = Array.from(new Set(clientRequestIds)).slice(0, 100);
3368
+ const knownIds = uniqueIds.length > 0 ? `&${uniqueIds.map((id) => `clientRequestIds=${encodeURIComponent(id)}`).join("&")}` : "";
3369
+ return `${agentQueuedTurnsRoot}?conversationId=${encodeURIComponent(conversationId)}${knownIds}`;
3370
+ };
3371
+ const agentQueuedTurn = (queuedTurnId) => `${agentQueuedTurnsRoot}/${encodeURIComponent(queuedTurnId)}`;
2562
3372
  const mcp = {
2563
3373
  tools: `${BASE_URL}/api/mcp/tools`,
2564
3374
  servers: `${BASE_URL}/api/mcp/servers`
@@ -2567,6 +3377,8 @@ const mcpServer = (serverName) => `${BASE_URL}/api/mcp/servers/${serverName}`;
2567
3377
  const revertAgentVersion$1 = (agent_id) => `${agents({ path: `${agent_id}/revert` })}`;
2568
3378
  const files = () => `${BASE_URL}/api/files`;
2569
3379
  const filePreview = (fileId) => `${BASE_URL}/api/files/${encodeURIComponent(fileId)}/preview`;
3380
+ /** Owner-scoped usage touch so queued attachments outlive the upload-window TTL. */
3381
+ const fileUsage = () => `${BASE_URL}/api/files/usage`;
2570
3382
  const agentFiles = (agentId) => `${BASE_URL}/api/files/agent/${agentId}`;
2571
3383
  const images = () => `${files()}/images`;
2572
3384
  const avatar = () => `${images()}/avatar`;
@@ -2610,6 +3422,9 @@ const deletePrompt$1 = ({ _id, groupId }) => {
2610
3422
  };
2611
3423
  const getCategories$1 = () => `${BASE_URL}/api/categories`;
2612
3424
  const getAllPromptGroups$1 = () => `${prompts()}/all`;
3425
+ const schedules = () => `${BASE_URL}/api/schedules`;
3426
+ const schedule = (id) => `${schedules()}/${encodeURIComponent(id)}`;
3427
+ const runSchedule = (id) => `${schedule(id)}/run`;
2613
3428
  const skills = () => `${BASE_URL}/api/skills`;
2614
3429
  const importSkill$1 = () => `${skills()}/import`;
2615
3430
  const getSkill$1 = (id) => `${skills()}/${encodeURIComponent(id)}`;
@@ -2623,11 +3438,18 @@ const listSkillsWithFilters = (filter) => {
2623
3438
  };
2624
3439
  const skillFiles = (id) => `${getSkill$1(id)}/files`;
2625
3440
  const skillFile = (id, relativePath) => `${skillFiles(id)}/${encodeURIComponent(relativePath)}`;
3441
+ const insights = () => `${BASE_URL}/api/admin/insights`;
3442
+ const insightsAccess = () => `${insights()}/access`;
2626
3443
  const adminSkillsSync = () => `${BASE_URL}/api/admin/skills/sync`;
2627
3444
  const adminSkillsSyncStatus = () => `${adminSkillsSync()}/status`;
2628
3445
  const adminSkillsSyncRun = () => `${adminSkillsSync()}/run`;
2629
3446
  const adminSkillsSyncCredential = (credentialKey) => `${adminSkillsSync()}/credentials/${encodeURIComponent(credentialKey)}`;
2630
3447
  const skillStates = () => `${BASE_URL}/api/user/settings/skills/active`;
3448
+ const adminLangfuseConnection = () => `${BASE_URL}/api/admin/langfuse/connection`;
3449
+ const adminLangfuseConnectionTest = () => `${adminLangfuseConnection()}/test`;
3450
+ const adminLangfuseSessionLink = (conversationId) => `${adminLangfuseConnection()}/session/${encodeURIComponent(conversationId)}`;
3451
+ const toolFavorites = () => `${BASE_URL}/api/user/settings/favorites/tools`;
3452
+ const toolFavorite = (itemType, itemId) => `${toolFavorites()}/${itemType}/${encodeURIComponent(itemId)}`;
2631
3453
  const roles = () => `${BASE_URL}/api/roles`;
2632
3454
  const adminRoles = () => `${BASE_URL}/api/admin/roles`;
2633
3455
  const getRole$1 = (roleName) => `${roles()}/${encodeURIComponent(roleName)}`;
@@ -2652,7 +3474,8 @@ const disableTwoFactor$1 = () => `${BASE_URL}/api/auth/2fa/disable`;
2652
3474
  const regenerateBackupCodes$1 = () => `${BASE_URL}/api/auth/2fa/backup/regenerate`;
2653
3475
  const verifyTwoFactorTemp$1 = () => `${BASE_URL}/api/auth/2fa/verify-temp`;
2654
3476
  const memories = () => `${BASE_URL}/api/memories`;
2655
- const memory = (key) => `${memories()}/${encodeURIComponent(key)}`;
3477
+ const memory = (key, agentId) => `${memories()}/${encodeURIComponent(key)}${agentId ? `?agentId=${encodeURIComponent(agentId)}` : ""}`;
3478
+ const memoryById = (id, agentId) => `${memories()}/id/${encodeURIComponent(id)}${agentId ? `?agentId=${encodeURIComponent(agentId)}` : ""}`;
2656
3479
  const memoryPreferences = () => `${memories()}/preferences`;
2657
3480
  const searchPrincipals$1 = (params) => {
2658
3481
  const { q: query, limit, types } = params;
@@ -2830,9 +3653,11 @@ const UserOAuthOptionsSchema = OAuthOptionsBaseSchema.omit({
2830
3653
  const OboOptionsSchema = z.object({
2831
3654
  /** Scopes to request for the downstream MCP server (e.g., "api://<client-id>/Mcp.Tools.ReadWrite") */
2832
3655
  scopes: z.string().min(1) });
3656
+ const MCP_SERVER_TITLE_PATTERN = /* @__PURE__ */ new RegExp("^[\\p{L}\\p{N}][\\p{L}\\p{N}\\p{M}'’ -]*$", "u");
3657
+ const MCP_SERVER_TITLE_ERROR = "Title must start with a letter or number and can include spaces, hyphens, and apostrophes";
2833
3658
  const BaseOptionsSchema = z.object({
2834
- /** Display name for the MCP server - only letters, numbers, and spaces allowed */
2835
- title: z.string().regex(/^[a-zA-Z0-9 ]+$/, "Title can only contain letters, numbers, and spaces").optional(),
3659
+ /** Display name for the MCP server */
3660
+ title: z.string().regex(MCP_SERVER_TITLE_PATTERN, MCP_SERVER_TITLE_ERROR).optional(),
2836
3661
  /** Description of the MCP server */
2837
3662
  description: z.string().optional(),
2838
3663
  /**
@@ -2847,7 +3672,14 @@ const BaseOptionsSchema = z.object({
2847
3672
  /** Timeout (ms) for the long-lived SSE GET stream body before undici aborts it. Default: 300_000 (5 min). */
2848
3673
  sseReadTimeout: z.number().int().positive().optional(),
2849
3674
  initTimeout: z.number().int().nonnegative().optional(),
2850
- /** Controls visibility in chat dropdown menu (MCPSelect) */
3675
+ /**
3676
+ * Whether the server is offered in chat.
3677
+ *
3678
+ * `false` hides it from the chat dropdown (MCPSelect) AND bars it from the
3679
+ * chat selection a request carries, so a stale or hand-written request cannot
3680
+ * reach it either. It does not restrict agents, nor a server a model spec
3681
+ * pins through `mcpServers` — both are the operator's own choice.
3682
+ */
2851
3683
  chatMenu: z.boolean().optional(),
2852
3684
  /**
2853
3685
  * Controls server instruction behavior:
@@ -2903,6 +3735,26 @@ const ProxyUrlSchema = z.string().transform((val) => extractEnvVariable(val)).pi
2903
3735
  const protocol = new URL(val).protocol;
2904
3736
  return protocol === "http:" || protocol === "https:" || protocol === "socks:" || protocol === "socks5:";
2905
3737
  }, { message: "Proxy URL must use http://, https://, socks://, or socks5://" });
3738
+ const PROCESS_MCP_SERVER_FIELDS = new Set([
3739
+ "command",
3740
+ "args",
3741
+ "env",
3742
+ "cwd",
3743
+ "stderr"
3744
+ ]);
3745
+ function isProcessMCPServerField(field) {
3746
+ return PROCESS_MCP_SERVER_FIELDS.has(field);
3747
+ }
3748
+ function isProcessMCPServerConfig(value) {
3749
+ if (value == null || typeof value !== "object" || Array.isArray(value)) return false;
3750
+ const config = value;
3751
+ if (config.type === "stdio") return true;
3752
+ return Object.keys(config).some(isProcessMCPServerField);
3753
+ }
3754
+ function hasProcessMCPServerConfig(value) {
3755
+ if (value == null || typeof value !== "object" || Array.isArray(value)) return false;
3756
+ return Object.values(value).some(isProcessMCPServerConfig);
3757
+ }
2906
3758
  const StdioOptionsSchema = BaseOptionsSchema.extend({
2907
3759
  type: z.literal("stdio").default("stdio"),
2908
3760
  obo: z.undefined().optional(),
@@ -2935,7 +3787,12 @@ const StdioOptionsSchema = BaseOptionsSchema.extend({
2935
3787
  "pipe",
2936
3788
  "ignore",
2937
3789
  "inherit"
2938
- ]), z.number().int().nonnegative()]).optional()
3790
+ ]), z.number().int().nonnegative()]).optional(),
3791
+ /**
3792
+ * Working directory for the spawned process. Supplied by Agent Plugins
3793
+ * packages, which resolve and contain the path before it reaches this schema.
3794
+ */
3795
+ cwd: z.string().optional()
2939
3796
  });
2940
3797
  const WebSocketOptionsSchema = BaseOptionsSchema.extend({
2941
3798
  type: z.literal("websocket").default("websocket"),
@@ -3070,7 +3927,10 @@ const defaultSocialLogins = [
3070
3927
  "discord",
3071
3928
  "saml"
3072
3929
  ];
3073
- const BASE_ONLY_CONFIG_SECTIONS = [];
3930
+ const BASE_ONLY_CONFIG_SECTIONS = ["filters"];
3931
+ /** Sections that may be stored in the tenant's base config document but must
3932
+ * not be overridden or tombstoned by role, group, or user config documents. */
3933
+ const BASE_PRINCIPAL_CONFIG_SECTIONS = ["langfuse"];
3074
3934
  const defaultRetrievalModels = [
3075
3935
  "gpt-4o",
3076
3936
  "o1-preview-2024-09-12",
@@ -3095,6 +3955,12 @@ const defaultRetrievalModels = [
3095
3955
  ];
3096
3956
  const excludedKeys = new Set([
3097
3957
  "conversationId",
3958
+ "agentEventBinding",
3959
+ "agentEventActor",
3960
+ "agentEventActorReconciliations",
3961
+ "agentEventActorEpoch",
3962
+ "agentEventActorLegacyTurn",
3963
+ "subagentThread",
3098
3964
  "title",
3099
3965
  "iconURL",
3100
3966
  "greeting",
@@ -3106,6 +3972,8 @@ const excludedKeys = new Set([
3106
3972
  "isTemporary",
3107
3973
  "messages",
3108
3974
  "isArchived",
3975
+ "pinned",
3976
+ "archivedAt",
3109
3977
  "tags",
3110
3978
  "user",
3111
3979
  "__v",
@@ -3154,6 +4022,32 @@ function isPrivateIPv4Literal(value) {
3154
4022
  if (a >= 224) return true;
3155
4023
  return false;
3156
4024
  }
4025
+ /**
4026
+ * Mirrors `hasPrivateEmbeddedIPv4` in `@librechat/api`'s ip helpers: 6to4, NAT64, and Teredo
4027
+ * carry an IPv4 address inside the IPv6 one, and the runtime guard blocks those when the
4028
+ * embedded address is private. Kept in sync so an operator can exempt what the runtime blocks.
4029
+ */
4030
+ function hasPrivateEmbeddedIPv4Literal(value) {
4031
+ const is6to4 = value.startsWith("2002:");
4032
+ const isNat64 = value.startsWith("64:ff9b::");
4033
+ const isTeredo = value.startsWith("2001::");
4034
+ if (!is6to4 && !isNat64 && !isTeredo) return false;
4035
+ const segments = value.split(":").filter((segment) => segment !== "");
4036
+ const pair = is6to4 ? segments.slice(1, 3) : segments.slice(-2);
4037
+ if (pair.length !== 2) return false;
4038
+ const hi = parseInt(pair[0], 16);
4039
+ const lo = parseInt(pair[1], 16);
4040
+ if (isNaN(hi) || isNaN(lo)) return false;
4041
+ /** RFC 4380: Teredo stores the external IPv4 as a bitwise complement. */
4042
+ const high = isTeredo ? ~hi : hi;
4043
+ const low = isTeredo ? ~lo : lo;
4044
+ return isPrivateIPv4Literal([
4045
+ high >> 8 & 255,
4046
+ high & 255,
4047
+ low >> 8 & 255,
4048
+ low & 255
4049
+ ].join("."));
4050
+ }
3157
4051
  function isPrivateIPv6Literal(value) {
3158
4052
  if (!value.includes(":")) return false;
3159
4053
  if (value === "::1" || value === "::") return true;
@@ -3164,7 +4058,7 @@ function isPrivateIPv6Literal(value) {
3164
4058
  }
3165
4059
  const mappedMatch = value.match(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
3166
4060
  if (mappedMatch) return isPrivateIPv4Literal(mappedMatch[1]);
3167
- return false;
4061
+ return hasPrivateEmbeddedIPv4Literal(value);
3168
4062
  }
3169
4063
  /**
3170
4064
  * Mirrors the allowedAddresses parser in `@librechat/api`'s auth helpers.
@@ -3381,6 +4275,7 @@ let AgentCapabilities = /* @__PURE__ */ function(AgentCapabilities) {
3381
4275
  AgentCapabilities["end_after_tools"] = "end_after_tools";
3382
4276
  AgentCapabilities["deferred_tools"] = "deferred_tools";
3383
4277
  AgentCapabilities["execute_code"] = "execute_code";
4278
+ AgentCapabilities["stateful_code_sessions"] = "stateful_code_sessions";
3384
4279
  AgentCapabilities["file_search"] = "file_search";
3385
4280
  AgentCapabilities["web_search"] = "web_search";
3386
4281
  AgentCapabilities["artifacts"] = "artifacts";
@@ -3388,9 +4283,13 @@ let AgentCapabilities = /* @__PURE__ */ function(AgentCapabilities) {
3388
4283
  AgentCapabilities["actions"] = "actions";
3389
4284
  AgentCapabilities["context"] = "context";
3390
4285
  AgentCapabilities["skills"] = "skills";
4286
+ AgentCapabilities["memory"] = "memory";
4287
+ AgentCapabilities["ask_user_question"] = "ask_user_question";
3391
4288
  AgentCapabilities["tools"] = "tools";
3392
4289
  AgentCapabilities["chain"] = "chain";
3393
4290
  AgentCapabilities["ocr"] = "ocr";
4291
+ AgentCapabilities["run_in_background"] = "run_in_background";
4292
+ AgentCapabilities["tool_intents"] = "tool_intents";
3394
4293
  return AgentCapabilities;
3395
4294
  }({});
3396
4295
  const defaultAssistantsVersion = {
@@ -3398,7 +4297,14 @@ const defaultAssistantsVersion = {
3398
4297
  ["azureAssistants"]: 1
3399
4298
  };
3400
4299
  const baseEndpointSchema = z.object({
3401
- streamRate: z.number().optional(),
4300
+ /**
4301
+ * Milliseconds between visible streamed chunks. Agents SDK-backed
4302
+ * providers (openAI, custom, anthropic, google, bedrock, agents) smooth
4303
+ * adaptively at 25ms by default; set to override the cadence, 0 to
4304
+ * disable smoothing. Legacy Assistants and Ollama paths instead sleep
4305
+ * this long per provider chunk (default 1ms), with no adaptive smoothing.
4306
+ */
4307
+ streamRate: z.number().min(0).optional(),
3402
4308
  baseURL: z.string().optional(),
3403
4309
  /**
3404
4310
  * Custom request headers forwarded to the provider on every request. Values
@@ -3426,6 +4332,53 @@ const baseEndpointSchema = z.object({
3426
4332
  * completes (legacy behavior).
3427
4333
  */
3428
4334
  titleTiming: z.union([z.literal("immediate"), z.literal("final")]).optional(),
4335
+ /**
4336
+ * Agent activity groups: collapse each contiguous block of reasoning and
4337
+ * tool calls under a generated one-line header. Mirrors the title options
4338
+ * above — `activityLabel` enables it (like `titleConvo`), the rest tune
4339
+ * the fast model that writes the label.
4340
+ *
4341
+ * NOTE: fields added here reach `endpoints.all` automatically (that schema
4342
+ * is `baseEndpointSchema.omit({ baseURL })`), but NOT Azure — see the
4343
+ * enumerated `.pick()` in `azureEndpointSchema` below.
4344
+ */
4345
+ activityLabel: z.boolean().optional(),
4346
+ /** Model used to write activity labels. Defaults to `titleModel`, then the agent's model. */
4347
+ activityModel: z.string().optional(),
4348
+ /** Endpoint whose credentials the label model runs on. Defaults to the agent's endpoint. */
4349
+ activityEndpoint: z.string().optional(),
4350
+ /** Overrides the system prompt used to write activity labels. */
4351
+ activityPrompt: z.string().optional(),
4352
+ /** Cost cap: maximum labels generated per run. Default 20. */
4353
+ activityMaxPerRun: z.number().int().positive().optional(),
4354
+ /** Per-entry truncation of tool input/output in the label prompt. Default 600. */
4355
+ activityCharLimit: z.number().int().positive().optional(),
4356
+ /** Generates one parent summary for each run phase containing 2+ activities. */
4357
+ activityPhaseLabel: z.boolean().optional(),
4358
+ /** Model used for phase summaries. Defaults to activityModel, titleModel, then the run model. */
4359
+ activityPhaseModel: z.string().optional(),
4360
+ /** Endpoint whose credentials the phase summary model uses. Defaults to activityEndpoint. */
4361
+ activityPhaseEndpoint: z.string().optional(),
4362
+ /** Overrides the dedicated phase-summary system prompt. */
4363
+ activityPhasePrompt: z.string().optional(),
4364
+ /** Cost cap: maximum phase summaries generated per run. Default 5. */
4365
+ activityPhaseMaxPerRun: z.number().int().positive().optional(),
4366
+ /** Generates a live orientation label for sufficiently long top-level response reasoning. */
4367
+ reasoningLabel: z.boolean().optional(),
4368
+ /** Model used for reasoning labels. Defaults to activityModel, titleModel, then run model. */
4369
+ reasoningLabelModel: z.string().optional(),
4370
+ /** Endpoint receiving the bounded visible-reasoning snapshot. Defaults to activityEndpoint. */
4371
+ reasoningLabelEndpoint: z.string().optional(),
4372
+ /** Overrides the dedicated reasoning-label system prompt. */
4373
+ reasoningLabelPrompt: z.string().optional(),
4374
+ /** Characters required before the first reasoning label. Default 500. */
4375
+ reasoningLabelMinChars: z.number().int().positive().optional(),
4376
+ /** New characters required between streaming revisions. Default 400. */
4377
+ reasoningLabelUpdateChars: z.number().int().positive().optional(),
4378
+ /** Minimum milliseconds between streaming revisions. Default 3000. */
4379
+ reasoningLabelUpdateIntervalMs: z.number().int().nonnegative().optional(),
4380
+ /** Cost cap: maximum reasoning-label provider calls attempted per run. Default 8. */
4381
+ reasoningLabelMaxPerRun: z.number().int().positive().optional(),
3429
4382
  /** Maximum characters allowed in a single tool result before truncation. */
3430
4383
  maxToolResultChars: z.number().positive().optional()
3431
4384
  });
@@ -3466,6 +4419,11 @@ const assistantEndpointSchema = baseEndpointSchema.merge(z.object({
3466
4419
  "tools"
3467
4420
  ]),
3468
4421
  apiKey: z.string().optional(),
4422
+ /** Masked preview of the API key, stored at write time so admin
4423
+ * reads can show which key is configured without returning the secret.
4424
+ * Shared by both `endpoints.assistants` and `endpoints.azureAssistants`,
4425
+ * which both use this schema. */
4426
+ apiKeyPreview: z.string().optional(),
3469
4427
  models: z.object({
3470
4428
  default: z.array(modelItemSchema).min(1),
3471
4429
  fetch: z.boolean().optional(),
@@ -3483,6 +4441,8 @@ const defaultAgentCapabilities = [
3483
4441
  "actions",
3484
4442
  "context",
3485
4443
  "skills",
4444
+ "memory",
4445
+ "ask_user_question",
3486
4446
  "tools",
3487
4447
  "chain",
3488
4448
  "ocr"
@@ -3528,23 +4488,304 @@ const remoteApiAuthSchema = z.object({
3528
4488
  oidc: remoteApiOidcSchema.optional()
3529
4489
  });
3530
4490
  const remoteApiSchema = z.object({ auth: remoteApiAuthSchema.optional() });
4491
+ /**
4492
+ * Permission mode applied to a tool call. Mirrors `@librechat/agents`'s
4493
+ * `ToolPolicyMode` 1:1.
4494
+ *
4495
+ * - `default`: ask the user about anything not explicitly allowed (default-on).
4496
+ * - `dontAsk`: deny anything not explicitly allowed (headless / API-key flows).
4497
+ * - `bypass`: auto-approve everything that isn't explicitly denied
4498
+ * (the user-facing "stop asking me" toggle).
4499
+ *
4500
+ * Subagents inherit the parent's mode; this is enforced by the SDK and not
4501
+ * overridable per-subagent.
4502
+ */
4503
+ const toolApprovalModeSchema = z.enum([
4504
+ "default",
4505
+ "dontAsk",
4506
+ "bypass"
4507
+ ]);
4508
+ /**
4509
+ * Per-endpoint tool-approval policy.
4510
+ *
4511
+ * Shape mirrors `@librechat/agents`'s `ToolPolicyConfig` so the host can map it
4512
+ * directly into `createToolPolicyHook(config)`. The SDK does the evaluation
4513
+ * (`deny → ask → allow → bypass → dontAsk → fallthrough(ask)`); this config
4514
+ * just describes the surface.
4515
+ *
4516
+ * Conventions:
4517
+ * - All list entries are matched as globs (`*`). Use `mcp:server:*` to scope
4518
+ * a rule to every tool from a single MCP server.
4519
+ * - `deny` always wins, including under `bypass`.
4520
+ * - `enabled: false` is a LibreChat-only kill switch that disables the entire
4521
+ * HITL machinery for this endpoint (no checkpointer, no hooks, no prompts).
4522
+ * This is admin-level; users toggle prompting via `mode: 'bypass'` instead.
4523
+ */
4524
+ /**
4525
+ * A programmatic tool-approval hook loaded from a module at startup.
4526
+ *
4527
+ * The referenced module's default export must be a builder
4528
+ * `(options?) => ToolApprovalHookFactory` (see `@librechat/api`'s `registerToolApprovalHook`).
4529
+ * Hooks compose with the static `allow`/`deny`/`ask` policy above and can only TIGHTEN it
4530
+ * (the SDK folds decisions `deny → ask → allow`). This is admin-level config — the module is
4531
+ * dynamically imported and executed in-process, so only reference trusted code.
4532
+ */
4533
+ const toolApprovalHookConfigSchema = z.object({
4534
+ /**
4535
+ * Module specifier to import: a bare package name (e.g. `@acme/approval-hooks`) or a path —
4536
+ * absolute, or relative to the app root. Its default export is the hook builder.
4537
+ */
4538
+ module: z.string().min(1),
4539
+ /** Optional regex matched against the tool name; omit to run for every tool. */
4540
+ matcher: z.string().optional(),
4541
+ /** Static options forwarded to the module's builder; the hook's own per-call config. */
4542
+ options: z.record(z.unknown()).optional()
4543
+ });
4544
+ const toolApprovalPolicySchema = z.object({
4545
+ enabled: z.boolean().optional(),
4546
+ mode: toolApprovalModeSchema.optional(),
4547
+ allow: z.array(z.string()).optional(),
4548
+ deny: z.array(z.string()).optional(),
4549
+ ask: z.array(z.string()).optional(),
4550
+ /** Optional reason template surfaced in the prompt; `{tool}` is interpolated. */
4551
+ reason: z.string().optional(),
4552
+ /**
4553
+ * Programmatic policy hooks loaded from modules at startup. They layer on top of the
4554
+ * static lists above for dynamic, context-aware decisions the lists can't express
4555
+ * (per-args, per-agent, per-user). See {@link toolApprovalHookConfigSchema}.
4556
+ *
4557
+ * BASE-CONFIG ONLY: hooks are imported + registered once, process-wide, at server
4558
+ * startup — they are NOT reloaded from per-role/user/tenant admin overrides. Encode
4559
+ * per-user/tenant behavior INSIDE the hook (via its runtime context), not by varying the
4560
+ * module list per override. Honored only when `enabled` is true.
4561
+ */
4562
+ hooks: z.array(toolApprovalHookConfigSchema).optional()
4563
+ }).optional();
4564
+ /**
4565
+ * Durable checkpointer backing human-in-the-loop resume.
4566
+ *
4567
+ * When `toolApproval.enabled` is true, a run that pauses for review suspends its
4568
+ * LangGraph state to a checkpoint; resuming rebuilds that state on a *fresh* `Run`
4569
+ * — possibly on a different replica, or the same worker after a restart. That only
4570
+ * works if the checkpoint outlives the original request, so HITL needs a durable
4571
+ * saver, not the SDK's process-local `MemorySaver` fallback.
4572
+ *
4573
+ * Defaults are zero-config: with `toolApproval.enabled` on and no `checkpointer`
4574
+ * block, LibreChat persists checkpoints to its primary MongoDB, so resume works
4575
+ * across replicas out of the box.
4576
+ *
4577
+ * - `type: 'mongo'` (default) — persist to the app database; survives restarts and
4578
+ * resolves on any replica. A TTL index reclaims runs that are never resolved.
4579
+ * - `type: 'memory'` — process-local only. Paused runs do NOT survive a restart and
4580
+ * can only be resolved on the originating worker. Single-process / dev only.
4581
+ */
4582
+ const checkpointerTypeSchema = z.enum(["mongo", "memory"]);
4583
+ const checkpointerSchema = z.object({
4584
+ type: checkpointerTypeSchema.optional(),
4585
+ /**
4586
+ * Approval window, in seconds: how long a paused run waits for a decision
4587
+ * before it is reclaimed. Drives both the Mongo TTL index on checkpoints and
4588
+ * the pending-action expiry, keeping the two layers in lockstep. Defaults to
4589
+ * 86400 (24h). Raise it for longer review windows.
4590
+ */
4591
+ ttl: z.number().int().positive().optional(),
4592
+ /** Advanced: override the Mongo collection names used for checkpoints. */
4593
+ checkpointCollectionName: z.string().optional(),
4594
+ checkpointWritesCollectionName: z.string().optional()
4595
+ }).optional();
4596
+ const codeEnvironmentBaseURLSchema = z.string().trim().url().refine((value) => {
4597
+ try {
4598
+ const url = new URL(value);
4599
+ return (url.protocol === "http:" || url.protocol === "https:") && !value.includes("?") && !value.includes("#") && url.search.length === 0 && url.hash.length === 0;
4600
+ } catch {
4601
+ return false;
4602
+ }
4603
+ }, { message: "Code environment baseURL must be an HTTP(S) base URL without query or fragment" });
4604
+ function isSecureCodeEnvironmentControlURL(baseURL) {
4605
+ try {
4606
+ const url = new URL(baseURL.trim());
4607
+ if (url.protocol === "https:") return true;
4608
+ if (url.protocol !== "http:") return false;
4609
+ return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
4610
+ } catch {
4611
+ return false;
4612
+ }
4613
+ }
4614
+ const codeEnvironmentPermissionDecisionSchema = z.enum([
4615
+ "allow",
4616
+ "ask",
4617
+ "deny"
4618
+ ]);
4619
+ const codeEnvironmentPermissionFieldSchema = z.object({
4620
+ allowed: z.array(codeEnvironmentPermissionDecisionSchema).min(1),
4621
+ default: codeEnvironmentPermissionDecisionSchema.optional().default("ask")
4622
+ }).strict().superRefine((field, context) => {
4623
+ if (!field.allowed.includes(field.default)) context.addIssue({
4624
+ code: z.ZodIssueCode.custom,
4625
+ path: ["default"],
4626
+ message: "Permission default must be included in allowed values"
4627
+ });
4628
+ });
4629
+ /**
4630
+ * Typed user-tunable surface for one attached code environment. Omitted fields
4631
+ * remain fixed at LibreChat's safe baseline. Isolation, networking, mounts,
4632
+ * privileged execution, and secrets are deliberately not representable here.
4633
+ */
4634
+ const codeEnvironmentUserConfigSchema = z.object({ permissions: z.object({
4635
+ fileWrite: codeEnvironmentPermissionFieldSchema.optional(),
4636
+ commandExecution: codeEnvironmentPermissionFieldSchema.optional()
4637
+ }).strict().optional() }).strict();
4638
+ const codeEnvironmentUserSettingsSchema = z.object({ permissions: z.object({
4639
+ fileWrite: codeEnvironmentPermissionDecisionSchema.optional(),
4640
+ commandExecution: codeEnvironmentPermissionDecisionSchema.optional()
4641
+ }).strict().optional() }).strict();
3531
4642
  const agentsEndpointSchema = baseEndpointSchema.omit({ baseURL: true }).merge(z.object({
3532
4643
  recursionLimit: z.number().optional(),
3533
4644
  disableBuilder: z.boolean().optional().default(false),
3534
4645
  maxRecursionLimit: z.number().optional(),
4646
+ /** Max cumulative bytes a single streamed tool call's arguments may reach before the run
4647
+ * aborts. Defaults to 64 KiB in the agents SDK; `0` disables the guard. */
4648
+ maxToolCallArgBytes: z.number().optional(),
4649
+ /** Max streamed chunk events per model generation before the run aborts. Off by default. */
4650
+ maxDeltaEventsPerTurn: z.number().optional(),
4651
+ /** Per-tool overrides of `maxToolCallArgBytes`, keyed by model-facing tool name; `0`
4652
+ * disables the guard for that tool only. Merged over LibreChat's shipped default of
4653
+ * `{ create_file: 131072 }`. */
4654
+ maxToolCallArgBytesByTool: z.record(z.number()).optional(),
3535
4655
  maxCitations: z.number().min(1).max(50).optional().default(30),
3536
4656
  maxCitationsPerFile: z.number().min(1).max(10).optional().default(7),
3537
4657
  minRelevanceScore: z.number().min(0).max(1).optional().default(.45),
4658
+ /** Maximum explicit subagents per agent (`agent_ids` and `graphs`); raised from
4659
+ * the shipped default of 10 for orchestration-heavy deployments, bounded by
4660
+ * `MAX_SUBAGENTS_CEILING`. */
4661
+ maxSubagents: z.number().int().min(1).max(50).optional().default(10),
3538
4662
  allowedProviders: z.array(z.union([z.string(), eModelEndpointSchema])).optional(),
3539
4663
  capabilities: z.array(z.nativeEnum(AgentCapabilities)).optional().default(defaultAgentCapabilities),
4664
+ /** Controls which workspace-sharing scopes users may select for stateful code sessions.
4665
+ * Omit this block to preserve the legacy behavior of allowing every scope. */
4666
+ statefulCodeSessions: z.object({
4667
+ allowedEnvironments: z.array(z.enum(STATEFUL_CODE_ENVIRONMENTS)).min(1),
4668
+ /** Operator-managed execution environments. Attached entries route to a
4669
+ * Code API deployment backed by an outbound librechat-code worker. */
4670
+ environments: z.array(z.object({
4671
+ id: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/),
4672
+ name: z.string().min(1).max(100),
4673
+ type: z.enum(["managed", "attached"]),
4674
+ baseURL: codeEnvironmentBaseURLSchema,
4675
+ default: z.boolean().optional(),
4676
+ /** Server-only outbound worker route. Removed from public config. */
4677
+ workerId: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/).optional(),
4678
+ /** Distinguishes operator policy from a principal-authorized
4679
+ * environment merged into request-scoped server config. */
4680
+ owner: z.enum(["deployment", "principal"]).optional().default("deployment"),
4681
+ /** Administrator-controlled user-tunable settings. Only fields
4682
+ * represented here may be changed by a principal. */
4683
+ configSchema: codeEnvironmentUserConfigSchema.optional(),
4684
+ /** Request-scoped effective settings for a principal-owned environment.
4685
+ * Deployment config should define defaults through configSchema instead. */
4686
+ settings: codeEnvironmentUserSettingsSchema.optional(),
4687
+ /** Server-only enrollment metadata. `tokenEnv` names an
4688
+ * environment variable and never contains the token itself. */
4689
+ pairing: z.object({
4690
+ workerId: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/).optional(),
4691
+ allowPrincipalWorkers: z.boolean().optional().default(false),
4692
+ tokenEnv: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/)
4693
+ }).superRefine((pairing, pairingContext) => {
4694
+ if (pairing.workerId != null || pairing.allowPrincipalWorkers === true) return;
4695
+ pairingContext.addIssue({
4696
+ code: z.ZodIssueCode.custom,
4697
+ message: "Pairing requires a workerId or principal workers"
4698
+ });
4699
+ }).optional()
4700
+ })).optional()
4701
+ }).superRefine((value, context) => {
4702
+ if (!value?.environments) return;
4703
+ const ids = /* @__PURE__ */ new Set();
4704
+ let defaults = 0;
4705
+ let executableEnvironments = 0;
4706
+ for (const environment of value.environments) {
4707
+ const pairingOnly = environment.pairing?.allowPrincipalWorkers === true && environment.pairing.workerId == null && environment.workerId == null;
4708
+ if (environment.pairing != null && environment.type !== "attached") context.addIssue({
4709
+ code: z.ZodIssueCode.custom,
4710
+ message: "Only attached code environments may configure pairing",
4711
+ path: [
4712
+ "environments",
4713
+ environment.id,
4714
+ "pairing"
4715
+ ]
4716
+ });
4717
+ if (environment.pairing != null && environment.owner !== "deployment") context.addIssue({
4718
+ code: z.ZodIssueCode.custom,
4719
+ message: "Only deployment-owned code environments may configure pairing",
4720
+ path: [
4721
+ "environments",
4722
+ environment.id,
4723
+ "pairing"
4724
+ ]
4725
+ });
4726
+ if (environment.pairing != null && !isSecureCodeEnvironmentControlURL(environment.baseURL)) context.addIssue({
4727
+ code: z.ZodIssueCode.custom,
4728
+ message: "Paired code environments require HTTPS outside loopback development",
4729
+ path: [
4730
+ "environments",
4731
+ environment.id,
4732
+ "baseURL"
4733
+ ]
4734
+ });
4735
+ if (environment.workerId != null && environment.pairing?.workerId != null && environment.workerId !== environment.pairing.workerId) context.addIssue({
4736
+ code: z.ZodIssueCode.custom,
4737
+ message: "Code environment workerId must match pairing.workerId",
4738
+ path: [
4739
+ "environments",
4740
+ environment.id,
4741
+ "workerId"
4742
+ ]
4743
+ });
4744
+ if (pairingOnly && environment.default === true) context.addIssue({
4745
+ code: z.ZodIssueCode.custom,
4746
+ message: "Pairing-only code control planes cannot be execution defaults",
4747
+ path: [
4748
+ "environments",
4749
+ environment.id,
4750
+ "default"
4751
+ ]
4752
+ });
4753
+ if (ids.has(environment.id)) context.addIssue({
4754
+ code: z.ZodIssueCode.custom,
4755
+ message: `Duplicate code environment id: ${environment.id}`,
4756
+ path: ["environments"]
4757
+ });
4758
+ ids.add(environment.id);
4759
+ if (!pairingOnly) {
4760
+ executableEnvironments += 1;
4761
+ if (environment.default === true) defaults += 1;
4762
+ }
4763
+ }
4764
+ if (executableEnvironments > 0 && defaults !== 1) context.addIssue({
4765
+ code: z.ZodIssueCode.custom,
4766
+ message: "Exactly one stateful code environment must be the default",
4767
+ path: ["environments"]
4768
+ });
4769
+ }).optional(),
4770
+ /** Optional trusted origin for in-process agent event delivery. */
4771
+ eventDriven: z.object({ selfUrl: z.string().url().optional() }).optional(),
4772
+ /** Conversational background-task delivery policy. Automatic completion wakeups are
4773
+ * enabled unless an administrator explicitly restores poll-only behavior. */
4774
+ backgroundTasks: z.object({ completionWakeups: z.boolean().optional().default(true) }).optional(),
3540
4775
  skills: z.object({ maxCatalogSkills: z.number().int().min(1).max(100).optional() }).optional(),
3541
- remoteApi: remoteApiSchema.optional()
4776
+ remoteApi: remoteApiSchema.optional(),
4777
+ /** Human-in-the-loop tool approval policy. Off by default. */
4778
+ toolApproval: toolApprovalPolicySchema,
4779
+ /** Durable checkpointer backing tool-approval and Ask User resume.
4780
+ * Defaults to the app's MongoDB when either flow needs it. */
4781
+ checkpointer: checkpointerSchema
3542
4782
  })).default({
3543
4783
  disableBuilder: false,
3544
4784
  capabilities: defaultAgentCapabilities,
3545
4785
  maxCitations: 30,
3546
4786
  maxCitationsPerFile: 7,
3547
- minRelevanceScore: .45
4787
+ minRelevanceScore: .45,
4788
+ maxSubagents: 10
3548
4789
  });
3549
4790
  const paramDefinitionSchema = z.object({
3550
4791
  key: z.string(),
@@ -3562,7 +4803,11 @@ const paramDefinitionSchema = z.object({
3562
4803
  range: z.object({
3563
4804
  min: z.number(),
3564
4805
  max: z.number(),
3565
- step: z.number().optional()
4806
+ step: z.number().optional(),
4807
+ positiveMin: z.number().optional()
4808
+ }).refine((value) => value.positiveMin == null || value.positiveMin <= value.max, {
4809
+ message: "range.positiveMin cannot exceed range.max",
4810
+ path: ["positiveMin"]
3566
4811
  }).optional(),
3567
4812
  enumMappings: z.record(z.union([
3568
4813
  z.number(),
@@ -3597,6 +4842,9 @@ const paramDefinitionSchema = z.object({
3597
4842
  const endpointSchema = baseEndpointSchema.merge(z.object({
3598
4843
  name: z.string().refine((value) => !eModelEndpointSchema.safeParse(value).success, { message: `Value cannot be one of the default endpoint (EModelEndpoint) values: ${Object.values(EModelEndpoint).join(", ")}` }),
3599
4844
  apiKey: z.string(),
4845
+ /** Masked preview of the API key, stored at write time so admin
4846
+ * reads can show which key is configured without returning the secret. */
4847
+ apiKeyPreview: z.string().optional(),
3600
4848
  baseURL: z.string(),
3601
4849
  models: z.object({
3602
4850
  default: z.array(modelItemSchema).min(1),
@@ -3644,15 +4892,43 @@ const endpointSchema = baseEndpointSchema.merge(z.object({
3644
4892
  const azureEndpointSchema = z.object({
3645
4893
  groups: azureGroupConfigsSchema,
3646
4894
  assistants: z.boolean().optional()
3647
- }).and(endpointSchema.pick({
3648
- streamRate: true,
3649
- titleConvo: true,
3650
- titleMethod: true,
3651
- titleModel: true,
3652
- titlePrompt: true,
3653
- titleTiming: true,
3654
- titlePromptTemplate: true
3655
- }).partial());
4895
+ }).and(
4896
+ /**
4897
+ * Azure carries only the base-endpoint fields enumerated here. This is a
4898
+ * `.pick()`, NOT an omit, so a field added to `baseEndpointSchema` is
4899
+ * silently unavailable on Azure endpoints until it is listed below —
4900
+ * unlike `endpoints.all`, which omits and therefore inherits new fields
4901
+ * automatically. Keep this list in sync when adding endpoint options.
4902
+ */
4903
+ endpointSchema.pick({
4904
+ streamRate: true,
4905
+ titleConvo: true,
4906
+ titleMethod: true,
4907
+ titleModel: true,
4908
+ titlePrompt: true,
4909
+ titleTiming: true,
4910
+ titlePromptTemplate: true,
4911
+ activityLabel: true,
4912
+ activityModel: true,
4913
+ activityEndpoint: true,
4914
+ activityPrompt: true,
4915
+ activityMaxPerRun: true,
4916
+ activityCharLimit: true,
4917
+ activityPhaseLabel: true,
4918
+ activityPhaseModel: true,
4919
+ activityPhaseEndpoint: true,
4920
+ activityPhasePrompt: true,
4921
+ activityPhaseMaxPerRun: true,
4922
+ reasoningLabel: true,
4923
+ reasoningLabelModel: true,
4924
+ reasoningLabelEndpoint: true,
4925
+ reasoningLabelPrompt: true,
4926
+ reasoningLabelMinChars: true,
4927
+ reasoningLabelUpdateChars: true,
4928
+ reasoningLabelUpdateIntervalMs: true,
4929
+ reasoningLabelMaxPerRun: true
4930
+ }).partial()
4931
+ );
3656
4932
  /**
3657
4933
  * Vertex AI model configuration - similar to Azure model config
3658
4934
  * Allows specifying deployment name for each model
@@ -3688,15 +4964,20 @@ const anthropicEndpointSchema = baseEndpointSchema.merge(z.object({
3688
4964
  /** Optional: List of available models */
3689
4965
  models: z.array(z.string()).optional()
3690
4966
  }));
4967
+ /** Masked preview of the API key, stored at write time so admin
4968
+ * reads can show which key is configured without returning the secret. */
4969
+ const apiKeyPreviewSchema = z.string().optional();
3691
4970
  const ttsOpenaiSchema = z.object({
3692
4971
  url: z.string().optional(),
3693
4972
  apiKey: z.string(),
4973
+ apiKeyPreview: apiKeyPreviewSchema,
3694
4974
  model: z.string(),
3695
4975
  voices: z.array(z.string())
3696
4976
  });
3697
4977
  const ttsAzureOpenAISchema = z.object({
3698
4978
  instanceName: z.string(),
3699
4979
  apiKey: z.string(),
4980
+ apiKeyPreview: apiKeyPreviewSchema,
3700
4981
  deploymentName: z.string(),
3701
4982
  apiVersion: z.string(),
3702
4983
  model: z.string(),
@@ -3706,6 +4987,7 @@ const ttsElevenLabsSchema = z.object({
3706
4987
  url: z.string().optional(),
3707
4988
  websocketUrl: z.string().optional(),
3708
4989
  apiKey: z.string(),
4990
+ apiKeyPreview: apiKeyPreviewSchema,
3709
4991
  model: z.string(),
3710
4992
  voices: z.array(z.string()),
3711
4993
  voice_settings: z.object({
@@ -3719,10 +5001,12 @@ const ttsElevenLabsSchema = z.object({
3719
5001
  const ttsLocalaiSchema = z.object({
3720
5002
  url: z.string(),
3721
5003
  apiKey: z.string().optional(),
5004
+ apiKeyPreview: apiKeyPreviewSchema,
3722
5005
  voices: z.array(z.string()),
3723
5006
  backend: z.string()
3724
5007
  });
3725
5008
  const ttsSchema = z.object({
5009
+ allowedAddresses: allowedAddressesSchema,
3726
5010
  openai: ttsOpenaiSchema.optional(),
3727
5011
  azureOpenAI: ttsAzureOpenAISchema.optional(),
3728
5012
  elevenlabs: ttsElevenLabsSchema.optional(),
@@ -3731,15 +5015,18 @@ const ttsSchema = z.object({
3731
5015
  const sttOpenaiSchema = z.object({
3732
5016
  url: z.string().optional(),
3733
5017
  apiKey: z.string(),
5018
+ apiKeyPreview: apiKeyPreviewSchema,
3734
5019
  model: z.string()
3735
5020
  });
3736
5021
  const sttAzureOpenAISchema = z.object({
3737
5022
  instanceName: z.string(),
3738
5023
  apiKey: z.string(),
5024
+ apiKeyPreview: apiKeyPreviewSchema,
3739
5025
  deploymentName: z.string(),
3740
5026
  apiVersion: z.string()
3741
5027
  });
3742
5028
  const sttSchema = z.object({
5029
+ allowedAddresses: allowedAddressesSchema,
3743
5030
  openai: sttOpenaiSchema.optional(),
3744
5031
  azureOpenAI: sttAzureOpenAISchema.optional()
3745
5032
  });
@@ -3747,16 +5034,23 @@ const speechTab = z.object({
3747
5034
  conversationMode: z.boolean().optional(),
3748
5035
  advancedMode: z.boolean().optional(),
3749
5036
  speechToText: z.boolean().optional().or(z.object({
3750
- /** Keep in sync with STTProviders enum (defined below cannot reference due to eval order) */
3751
- engineSTT: z.enum(["openai", "azureOpenAI"]).optional(),
5037
+ /** Provider names remain valid for backward compatibility and are normalized for clients. */
5038
+ engineSTT: z.enum([
5039
+ "browser",
5040
+ "external",
5041
+ "openai",
5042
+ "azureOpenAI"
5043
+ ]).optional(),
3752
5044
  languageSTT: z.string().optional(),
3753
5045
  autoTranscribeAudio: z.boolean().optional(),
3754
5046
  decibelValue: z.number().optional(),
3755
5047
  autoSendText: z.number().optional()
3756
5048
  })).optional(),
3757
5049
  textToSpeech: z.boolean().optional().or(z.object({
3758
- /** Keep in sync with TTSProviders enum (defined below cannot reference due to eval order) */
5050
+ /** Provider names remain valid for backward compatibility and are normalized for clients. */
3759
5051
  engineTTS: z.enum([
5052
+ "browser",
5053
+ "external",
3760
5054
  "openai",
3761
5055
  "azureOpenAI",
3762
5056
  "elevenlabs",
@@ -3777,6 +5071,10 @@ let RateLimitPrefix = /* @__PURE__ */ function(RateLimitPrefix) {
3777
5071
  return RateLimitPrefix;
3778
5072
  }({});
3779
5073
  const rateLimitSchema = z.object({
5074
+ agentEvents: z.object({
5075
+ userMax: z.number().int().positive().optional(),
5076
+ userWindowInMinutes: z.number().positive().optional()
5077
+ }).optional(),
3780
5078
  fileUploads: z.object({
3781
5079
  ipMax: z.number().optional(),
3782
5080
  ipWindowInMinutes: z.number().optional(),
@@ -3868,6 +5166,7 @@ const interfaceSchema = z.object({
3868
5166
  webSearch: z.boolean().optional(),
3869
5167
  contextUsage: z.boolean().optional(),
3870
5168
  contextCost: z.boolean().optional(),
5169
+ feedback: z.boolean().optional(),
3871
5170
  currency: z.object({
3872
5171
  code: z.string(),
3873
5172
  rate: z.number().positive()
@@ -3901,6 +5200,23 @@ const interfaceSchema = z.object({
3901
5200
  share: z.boolean().optional(),
3902
5201
  public: z.boolean().optional(),
3903
5202
  snapshotFiles: z.boolean().optional()
5203
+ })]).optional(),
5204
+ schedules: z.union([z.boolean(), z.object({
5205
+ use: z.boolean().optional(),
5206
+ create: z.boolean().optional(),
5207
+ maxPerUser: z.number().int().min(0).optional(),
5208
+ minIntervalMinutes: z.number().int().min(1).optional(),
5209
+ autoDisableAfterFailures: z.number().int().min(1).optional(),
5210
+ fireConcurrency: z.number().int().min(1).optional(),
5211
+ /** Refuse schedules that are not filed under a chat project. Enforced on
5212
+ * create/update AND at every fire, so raising it later stops schedules
5213
+ * that predate the policy instead of grandfathering them. */
5214
+ requireProject: z.boolean().optional(),
5215
+ /** Pins every scheduled run to ONE chat project, ignoring any client
5216
+ * choice. Implies `requireProject`. The project must belong to the
5217
+ * schedule's owner, so a deployment-wide value only makes sense with a
5218
+ * per-user/per-role config override. */
5219
+ projectId: z.string().trim().min(1).optional()
3904
5220
  })]).optional()
3905
5221
  }).default({
3906
5222
  modelSelect: true,
@@ -3927,6 +5243,7 @@ const interfaceSchema = z.object({
3927
5243
  webSearch: true,
3928
5244
  contextUsage: true,
3929
5245
  contextCost: false,
5246
+ feedback: true,
3930
5247
  peoplePicker: {
3931
5248
  users: true,
3932
5249
  groups: true,
@@ -3996,12 +5313,14 @@ let SearchProviders = /* @__PURE__ */ function(SearchProviders) {
3996
5313
  SearchProviders["SERPER"] = "serper";
3997
5314
  SearchProviders["SEARXNG"] = "searxng";
3998
5315
  SearchProviders["TAVILY"] = "tavily";
5316
+ SearchProviders["KEENABLE"] = "keenable";
3999
5317
  return SearchProviders;
4000
5318
  }({});
4001
5319
  let ScraperProviders = /* @__PURE__ */ function(ScraperProviders) {
4002
5320
  ScraperProviders["FIRECRAWL"] = "firecrawl";
4003
5321
  ScraperProviders["SERPER"] = "serper";
4004
5322
  ScraperProviders["TAVILY"] = "tavily";
5323
+ ScraperProviders["KEENABLE"] = "keenable";
4005
5324
  return ScraperProviders;
4006
5325
  }({});
4007
5326
  let RerankerTypes = /* @__PURE__ */ function(RerankerTypes) {
@@ -4016,19 +5335,39 @@ let SafeSearchTypes = /* @__PURE__ */ function(SafeSearchTypes) {
4016
5335
  SafeSearchTypes[SafeSearchTypes["STRICT"] = 2] = "STRICT";
4017
5336
  return SafeSearchTypes;
4018
5337
  }({});
5338
+ /**
5339
+ * Normalizes a SearXNG engine list into the comma-separated form the API expects.
5340
+ * Accepts the YAML list or comma-separated string an operator may write, and is
5341
+ * applied both at the schema boundary and when loading the runtime config, since
5342
+ * `loadCustomConfig` returns the raw YAML object rather than the parsed result.
5343
+ */
5344
+ function normalizeSearxngEngines(engines) {
5345
+ if (engines == null) return;
5346
+ const normalized = (Array.isArray(engines) ? engines : engines.split(",")).map((engine) => engine.trim()).filter(Boolean);
5347
+ return normalized.length ? normalized.join(",") : void 0;
5348
+ }
4019
5349
  const webSearchSchema = z.object({
5350
+ allowedAddresses: allowedAddressesSchema,
4020
5351
  serperApiKey: z.string().optional().default("${SERPER_API_KEY}"),
5352
+ serperApiKeyPreview: apiKeyPreviewSchema,
4021
5353
  searxngInstanceUrl: z.string().optional().default("${SEARXNG_INSTANCE_URL}"),
4022
5354
  searxngApiKey: z.string().optional().default("${SEARXNG_API_KEY}"),
5355
+ searxngApiKeyPreview: apiKeyPreviewSchema,
4023
5356
  firecrawlApiKey: z.string().optional().default("${FIRECRAWL_API_KEY}"),
5357
+ firecrawlApiKeyPreview: apiKeyPreviewSchema,
4024
5358
  firecrawlApiUrl: z.string().optional().default("${FIRECRAWL_API_URL}"),
4025
5359
  firecrawlVersion: z.string().optional().default("${FIRECRAWL_VERSION}"),
4026
5360
  tavilyApiKey: z.string().optional().default("${TAVILY_API_KEY}"),
5361
+ tavilyApiKeyPreview: apiKeyPreviewSchema,
4027
5362
  tavilySearchUrl: z.string().optional().default("${TAVILY_SEARCH_URL}"),
4028
5363
  tavilyExtractUrl: z.string().optional().default("${TAVILY_EXTRACT_URL}"),
5364
+ keenableApiKey: z.string().optional().default("${KEENABLE_API_KEY}"),
5365
+ keenableApiUrl: z.string().optional().default("${KEENABLE_API_URL}"),
4029
5366
  jinaApiKey: z.string().optional().default("${JINA_API_KEY}"),
5367
+ jinaApiKeyPreview: apiKeyPreviewSchema,
4030
5368
  jinaApiUrl: z.string().optional().default("${JINA_API_URL}"),
4031
5369
  cohereApiKey: z.string().optional().default("${COHERE_API_KEY}"),
5370
+ cohereApiKeyPreview: apiKeyPreviewSchema,
4032
5371
  searchProvider: z.nativeEnum(SearchProviders).optional(),
4033
5372
  scraperProvider: z.nativeEnum(ScraperProviders).optional(),
4034
5373
  rerankerType: z.nativeEnum(RerankerTypes).optional(),
@@ -4061,6 +5400,16 @@ const webSearchSchema = z.object({
4061
5400
  tag: z.string().nullable().optional()
4062
5401
  }).optional()
4063
5402
  }).optional(),
5403
+ searxngSearchOptions: z.object({
5404
+ engines: z.union([z.string(), z.array(z.string())]).transform(normalizeSearxngEngines).optional(),
5405
+ language: z.string().optional(),
5406
+ timeRange: z.enum([
5407
+ "day",
5408
+ "month",
5409
+ "year"
5410
+ ]).optional(),
5411
+ timeout: z.number().int().positive().max(12e4).optional()
5412
+ }).optional(),
4064
5413
  tavilySearchOptions: z.object({
4065
5414
  searchDepth: z.enum([
4066
5415
  "basic",
@@ -4101,11 +5450,23 @@ const webSearchSchema = z.object({
4101
5450
  includeFavicon: z.boolean().optional(),
4102
5451
  format: z.enum(["markdown", "text"]).optional(),
4103
5452
  timeout: z.number().int().nonnegative().max(12e4).optional()
5453
+ }).optional(),
5454
+ keenableSearchOptions: z.object({
5455
+ maxResults: z.number().int().min(1).max(20).optional(),
5456
+ site: z.string().optional(),
5457
+ attributionTitle: z.string().optional(),
5458
+ timeout: z.number().int().nonnegative().max(12e4).optional()
5459
+ }).optional(),
5460
+ keenableScraperOptions: z.object({
5461
+ attributionTitle: z.string().optional(),
5462
+ timeout: z.number().int().nonnegative().max(12e4).optional()
4104
5463
  }).optional()
4105
5464
  });
4106
5465
  const ocrSchema = z.object({
5466
+ allowedAddresses: allowedAddressesSchema,
4107
5467
  mistralModel: z.string().optional(),
4108
5468
  apiKey: z.string().optional().default("${OCR_API_KEY}"),
5469
+ apiKeyPreview: apiKeyPreviewSchema,
4109
5470
  baseURL: z.string().optional().default("${OCR_BASEURL}"),
4110
5471
  strategy: z.nativeEnum(OCRStrategy).default("mistral_ocr")
4111
5472
  });
@@ -4163,6 +5524,10 @@ const contextPruningSchema = z.object({
4163
5524
  hardClearRatio: z.number().min(0).max(1).optional(),
4164
5525
  minPrunableToolChars: z.number().min(0).optional()
4165
5526
  });
5527
+ const retainRecentConfigSchema = z.object({
5528
+ turns: z.number().min(0).max(20).optional(),
5529
+ tokens: z.number().positive().optional()
5530
+ });
4166
5531
  const summarizationConfigSchema = z.object({
4167
5532
  enabled: z.boolean().optional(),
4168
5533
  provider: z.string().optional(),
@@ -4178,31 +5543,102 @@ const summarizationConfigSchema = z.object({
4178
5543
  updatePrompt: z.string().optional(),
4179
5544
  reserveRatio: z.number().min(0).max(1).optional(),
4180
5545
  maxSummaryTokens: z.number().positive().optional(),
4181
- contextPruning: contextPruningSchema.optional()
5546
+ contextPruning: contextPruningSchema.optional(),
5547
+ retainRecent: retainRecentConfigSchema.optional()
4182
5548
  });
4183
5549
  const customEndpointsSchema = z.array(endpointSchema.partial()).optional();
5550
+ let messageFilterRegexValidator = (value) => {
5551
+ try {
5552
+ new RegExp(value, "g");
5553
+ return true;
5554
+ } catch {
5555
+ return false;
5556
+ }
5557
+ };
5558
+ const setMessageFilterRegexValidator = (validate) => {
5559
+ messageFilterRegexValidator = validate;
5560
+ };
4184
5561
  const messageFilterPiiCustomPatternSchema = z.object({
4185
- id: z.string().min(1),
4186
- label: z.string().min(1),
4187
- regex: z.string().min(1).refine((value) => {
4188
- try {
4189
- new RegExp(value, "g");
4190
- return true;
4191
- } catch {
4192
- return false;
4193
- }
4194
- }, { message: "Invalid regex" })
5562
+ id: z.string().min(1).max(256),
5563
+ label: z.string().min(1).max(512),
5564
+ regex: z.string().min(1).max(512)
4195
5565
  });
4196
5566
  const messageFilterPiiSchema = z.object({
4197
- starterPatterns: z.array(z.string()).optional(),
4198
- customPatterns: z.array(messageFilterPiiCustomPatternSchema).optional()
5567
+ starterPatterns: z.array(z.string().max(256)).max(256).optional(),
5568
+ customPatterns: z.array(messageFilterPiiCustomPatternSchema).max(256).optional()
5569
+ }).superRefine((pii, context) => {
5570
+ let regexCharacters = 0;
5571
+ let regexInstructions = 0;
5572
+ for (let index = 0; index < (pii.customPatterns?.length ?? 0); index++) {
5573
+ const pattern = pii.customPatterns?.[index];
5574
+ if (pattern == null) continue;
5575
+ regexCharacters += pattern.regex.length;
5576
+ const result = messageFilterRegexValidator(pattern.regex);
5577
+ if (!(typeof result === "boolean" ? result : result.supported)) {
5578
+ context.addIssue({
5579
+ code: z.ZodIssueCode.custom,
5580
+ path: [
5581
+ "customPatterns",
5582
+ index,
5583
+ "regex"
5584
+ ],
5585
+ message: "Unsupported regex: not compatible with the RE2 engine (no backreferences, lookaround, or control escapes)"
5586
+ });
5587
+ continue;
5588
+ }
5589
+ if (typeof result !== "boolean" && result.programSize != null) regexInstructions += result.programSize;
5590
+ }
5591
+ if (regexCharacters > 8192) context.addIssue({
5592
+ code: z.ZodIssueCode.custom,
5593
+ path: ["customPatterns"],
5594
+ message: `Custom PII regexes may contain at most ${MAX_PII_CUSTOM_REGEX_CHARACTERS} characters in total`
5595
+ });
5596
+ if (regexInstructions > 8192) context.addIssue({
5597
+ code: z.ZodIssueCode.custom,
5598
+ path: ["customPatterns"],
5599
+ message: `Custom PII regexes may compile to at most ${MAX_PII_CUSTOM_REGEX_INSTRUCTIONS} instructions in total`
5600
+ });
4199
5601
  });
4200
5602
  const messageFilterSchema = z.object({ pii: messageFilterPiiSchema.optional() });
5603
+ const langfuseConfigSchema = z.object({
5604
+ enabled: z.boolean().optional(),
5605
+ publicKey: z.string().optional(),
5606
+ secretKey: z.string().optional(),
5607
+ /** Stable Langfuse project identity returned when credentials are verified. */
5608
+ projectId: z.string().optional(),
5609
+ /** Masked preview of the secret key, stored at write time so
5610
+ * admin reads can show which secret key is configured without returning the secret. */
5611
+ secretKeyPreview: z.string().optional(),
5612
+ /** Routing key for one of the deployment-configured tenant Langfuse destinations. */
5613
+ destination: z.string().optional(),
5614
+ /**
5615
+ * Custom request headers sent on every outbound Langfuse request — trace and
5616
+ * media export, feedback scores, and credential verification — for
5617
+ * self-hosted instances behind an authenticating proxy or gateway. Values
5618
+ * support `${ENV_VAR}` interpolation.
5619
+ *
5620
+ * Deployment-level only. Trace export batches spans from every user through
5621
+ * one exporter, so unlike endpoint headers these cannot carry per-user
5622
+ * placeholders. Headers referencing an unset variable, naming an
5623
+ * infrastructure secret, or carrying an invalid HTTP field name are dropped
5624
+ * with a warning rather than sent.
5625
+ *
5626
+ * Sent only when the deployment configures exactly one Langfuse origin, and
5627
+ * only to that origin. The map cannot say which endpoint it authenticates
5628
+ * to, so with several configured origins any choice of recipient would risk
5629
+ * disclosing a gateway credential to the others; a warning is logged instead.
5630
+ * Multi-destination deployments need per-destination headers, which this
5631
+ * schema does not yet express — and note the fanout collector forwards only
5632
+ * `Authorization` upstream regardless.
5633
+ */
5634
+ headers: z.record(z.string()).optional()
5635
+ });
4201
5636
  const configSchema = z.object({
4202
5637
  version: z.string(),
4203
5638
  cache: z.boolean().default(true),
4204
5639
  ocr: ocrSchema.optional(),
4205
5640
  webSearch: webSearchSchema.optional(),
5641
+ langfuse: langfuseConfigSchema.optional(),
4206
5642
  memory: memorySchema.optional(),
4207
5643
  summarization: summarizationConfigSchema.optional(),
4208
5644
  skillSync: skillSyncConfigSchema,
@@ -4238,9 +5674,17 @@ const configSchema = z.object({
4238
5674
  rateLimits: rateLimitSchema.optional(),
4239
5675
  fileConfig: fileConfigSchema.optional(),
4240
5676
  modelSpecs: specsConfigSchema.optional(),
5677
+ filters: filtersConfigSchema.optional(),
4241
5678
  messageFilter: messageFilterSchema.optional(),
4242
5679
  endpoints: z.object({
4243
5680
  allowedAddresses: allowedAddressesSchema,
5681
+ /**
5682
+ * Defaults applied to every endpoint. Omit-based, so options added to
5683
+ * `baseEndpointSchema` are inherited here automatically — no list to
5684
+ * maintain (contrast `azureEndpointSchema`, which enumerates via
5685
+ * `.pick()`). Resolution order at read sites is `all` > the named
5686
+ * endpoint > a custom endpoint's own config.
5687
+ */
4244
5688
  all: baseEndpointSchema.omit({ baseURL: true }).optional(),
4245
5689
  ["openAI"]: baseEndpointSchema.optional(),
4246
5690
  ["google"]: baseEndpointSchema.optional(),
@@ -4310,6 +5754,9 @@ const alternateName = {
4310
5754
  ["helicone"]: "Helicone"
4311
5755
  };
4312
5756
  const sharedOpenAIModels = [
5757
+ "gpt-5.6",
5758
+ "gpt-5.6-terra",
5759
+ "gpt-5.6-luna",
4313
5760
  "gpt-5.5",
4314
5761
  "gpt-5.5-pro",
4315
5762
  "chat-latest",
@@ -4333,9 +5780,12 @@ const sharedOpenAIModels = [
4333
5780
  "gpt-4o"
4334
5781
  ];
4335
5782
  const sharedAnthropicModels = [
5783
+ "claude-fable-5-1",
4336
5784
  "claude-fable-5",
5785
+ "claude-opus-5",
4337
5786
  "claude-opus-4-8",
4338
5787
  "claude-opus-4-7",
5788
+ "claude-sonnet-5",
4339
5789
  "claude-sonnet-4-6",
4340
5790
  "claude-opus-4-6",
4341
5791
  "claude-sonnet-4-5",
@@ -4356,18 +5806,26 @@ const sharedAnthropicModels = [
4356
5806
  "claude-3-5-sonnet-20240620",
4357
5807
  "claude-3-5-sonnet-latest"
4358
5808
  ];
5809
+ /**
5810
+ * Claude 4+ models are not invocable on-demand by their bare foundation-model
5811
+ * ID on the Converse path — Bedrock rejects those with "Invocation of model ID
5812
+ * ... with on-demand throughput isn't supported. Retry your request with the ID
5813
+ * or ARN of an inference profile that contains this model." Default to the
5814
+ * `global.` cross-region profile (no regional pricing premium, widest
5815
+ * availability); Opus 4.1 has no global profile, so it uses `us.`.
5816
+ */
4359
5817
  const bedrockModels = [
4360
- "anthropic.claude-fable-5",
4361
- "anthropic.claude-opus-4-8",
4362
- "anthropic.claude-opus-4-7",
4363
- "anthropic.claude-sonnet-4-6",
4364
- "anthropic.claude-opus-4-6-v1",
4365
- "anthropic.claude-sonnet-4-5-20250929-v1:0",
4366
- "anthropic.claude-haiku-4-5-20251001-v1:0",
4367
- "anthropic.claude-opus-4-1-20250805-v1:0",
4368
- "anthropic.claude-3-5-sonnet-20241022-v2:0",
4369
- "anthropic.claude-3-5-sonnet-20240620-v1:0",
4370
- "anthropic.claude-3-5-haiku-20241022-v1:0",
5818
+ "global.anthropic.claude-fable-5-1",
5819
+ "global.anthropic.claude-fable-5",
5820
+ "global.anthropic.claude-opus-5",
5821
+ "global.anthropic.claude-opus-4-8",
5822
+ "global.anthropic.claude-opus-4-7",
5823
+ "global.anthropic.claude-sonnet-5",
5824
+ "global.anthropic.claude-sonnet-4-6",
5825
+ "global.anthropic.claude-opus-4-6-v1",
5826
+ "global.anthropic.claude-sonnet-4-5-20250929-v1:0",
5827
+ "global.anthropic.claude-haiku-4-5-20251001-v1:0",
5828
+ "us.anthropic.claude-opus-4-1-20250805-v1:0",
4371
5829
  "cohere.command-r-v1:0",
4372
5830
  "cohere.command-r-plus-v1:0",
4373
5831
  "meta.llama2-13b-chat-v1",
@@ -4392,7 +5850,11 @@ const defaultModels = {
4392
5850
  ["assistants"]: [...sharedOpenAIModels, "chatgpt-4o-latest"],
4393
5851
  ["agents"]: sharedOpenAIModels,
4394
5852
  ["google"]: [
5853
+ "gemini-3.8-flash",
5854
+ "gemini-3.7-flash",
5855
+ "gemini-3.6-flash",
4395
5856
  "gemini-3.5-flash",
5857
+ "gemini-3.5-flash-lite",
4396
5858
  "gemini-3.1-pro-preview",
4397
5859
  "gemini-3.1-pro-preview-customtools",
4398
5860
  "gemini-3.1-flash-lite-preview",
@@ -4552,6 +6014,18 @@ let CacheKeys = /* @__PURE__ */ function(CacheKeys) {
4552
6014
  */
4553
6015
  CacheKeys["ROLES"] = "ROLES";
4554
6016
  /**
6017
+ * Key for cached group memberships used to resolve ACL user principals.
6018
+ */
6019
+ CacheKeys["USER_PRINCIPALS"] = "USER_PRINCIPALS";
6020
+ /**
6021
+ * Key for cached prompt group access ID sets (accessible, public, owned).
6022
+ */
6023
+ CacheKeys["PROMPT_GROUPS_ACCESS"] = "PROMPT_GROUPS_ACCESS";
6024
+ /**
6025
+ * Key for per-conversation stateful code sandbox prewarm/warm state.
6026
+ */
6027
+ CacheKeys["SANDBOX_PREWARM"] = "SANDBOX_PREWARM";
6028
+ /**
4555
6029
  * Key for the title generation cache.
4556
6030
  */
4557
6031
  CacheKeys["GEN_TITLE"] = "GEN_TITLE";
@@ -4621,6 +6095,10 @@ let CacheKeys = /* @__PURE__ */ function(CacheKeys) {
4621
6095
  */
4622
6096
  CacheKeys["OPENID_EXCHANGED_TOKENS"] = "OPENID_EXCHANGED_TOKENS";
4623
6097
  /**
6098
+ * Key for cached authenticated user documents.
6099
+ */
6100
+ CacheKeys["AUTH_USER_DOC"] = "AUTH_USER_DOC";
6101
+ /**
4624
6102
  * Key for OpenID session.
4625
6103
  */
4626
6104
  CacheKeys["OPENID_SESSION"] = "OPENID_SESSION";
@@ -4634,6 +6112,7 @@ let CacheKeys = /* @__PURE__ */ function(CacheKeys) {
4634
6112
  CacheKeys["ADMIN_OAUTH_EXCHANGE"] = "ADMIN_OAUTH_EXCHANGE";
4635
6113
  return CacheKeys;
4636
6114
  }({});
6115
+ const AUTH_USER_DOC_BY_ID_PREFIX = "auth-user-doc-byid";
4637
6116
  /**
4638
6117
  * Enum for violation types, used to identify, log, and cache violations.
4639
6118
  */
@@ -4757,6 +6236,18 @@ let ErrorTypes = /* @__PURE__ */ function(ErrorTypes) {
4757
6236
  */
4758
6237
  ErrorTypes["GOOGLE_TOOL_CONFLICT"] = "google_tool_conflict";
4759
6238
  /**
6239
+ * Google provider could not process a linked video (most often longer than the model accepts)
6240
+ */
6241
+ ErrorTypes["GOOGLE_VIDEO_UNPROCESSABLE"] = "google_video_unprocessable";
6242
+ /**
6243
+ * Required CodeAPI resources could not be restored before model invocation.
6244
+ */
6245
+ ErrorTypes["RESOURCE_RECOVERY_REQUIRED"] = "resource_recovery_required";
6246
+ /**
6247
+ * Agent selected a stateful Code API workspace scope disabled by the deployment.
6248
+ */
6249
+ ErrorTypes["STATEFUL_CODE_ENVIRONMENT_NOT_ALLOWED"] = "stateful_code_environment_not_allowed";
6250
+ /**
4760
6251
  * Invalid Agent Provider (excluded by Admin)
4761
6252
  */
4762
6253
  ErrorTypes["INVALID_AGENT_PROVIDER"] = "invalid_agent_provider";
@@ -4777,6 +6268,14 @@ let ErrorTypes = /* @__PURE__ */ function(ErrorTypes) {
4777
6268
  */
4778
6269
  ErrorTypes["AUTH_FAILED"] = "auth_failed";
4779
6270
  /**
6271
+ * Authentication rejected by a rate limiter
6272
+ */
6273
+ ErrorTypes["AUTH_RATE_LIMITED"] = "auth_rate_limited";
6274
+ /**
6275
+ * Authentication rejected because the account or IP is banned
6276
+ */
6277
+ ErrorTypes["AUTH_BANNED"] = "auth_banned";
6278
+ /**
4780
6279
  * Model refused to respond (content policy violation)
4781
6280
  */
4782
6281
  ErrorTypes["REFUSAL"] = "refusal";
@@ -4784,6 +6283,14 @@ let ErrorTypes = /* @__PURE__ */ function(ErrorTypes) {
4784
6283
  * SSE stream 404 — job completed, expired, or was deleted before the subscriber connected
4785
6284
  */
4786
6285
  ErrorTypes["STREAM_EXPIRED"] = "stream_expired";
6286
+ /**
6287
+ * Provider does not serve the requested model
6288
+ */
6289
+ ErrorTypes["MODEL_NOT_FOUND"] = "model_not_found";
6290
+ /**
6291
+ * Provider throttled or refused the request for exceeding a rate/spend allowance
6292
+ */
6293
+ ErrorTypes["MODEL_RATE_LIMIT"] = "model_rate_limit";
4787
6294
  return ErrorTypes;
4788
6295
  }({});
4789
6296
  /**
@@ -4849,6 +6356,10 @@ let SettingsTabValues = /* @__PURE__ */ function(SettingsTabValues) {
4849
6356
  */
4850
6357
  SettingsTabValues["SPEECH"] = "speech";
4851
6358
  /**
6359
+ * Tab for Langfuse Settings
6360
+ */
6361
+ SettingsTabValues["LANGFUSE"] = "langfuse";
6362
+ /**
4852
6363
  * Tab for Beta Features
4853
6364
  */
4854
6365
  SettingsTabValues["BETA"] = "beta";
@@ -4911,7 +6422,7 @@ let TTSProviders = /* @__PURE__ */ function(TTSProviders) {
4911
6422
  /** Enum for app-wide constants */
4912
6423
  let Constants = /* @__PURE__ */ function(Constants) {
4913
6424
  /**
4914
- * Key for the app's version. The placeholder `v0.8.7` is
6425
+ * Key for the app's version. The placeholder `v0.8.8-rc2` is
4915
6426
  * swapped in by `@rollup/plugin-replace` during `npm run build:data-provider`
4916
6427
  * using the value of the root `package.json`'s `version` field. Consumers
4917
6428
  * always import this via the built dist bundle (see `main` field in
@@ -4919,9 +6430,9 @@ let Constants = /* @__PURE__ */ function(Constants) {
4919
6430
  * substituted value. Only tests that import the TypeScript source directly
4920
6431
  * would observe the raw placeholder.
4921
6432
  */
4922
- Constants["VERSION"] = "v0.8.7";
6433
+ Constants["VERSION"] = "v0.8.8-rc2";
4923
6434
  /** Key for the Custom Config's version (librechat.yaml). */
4924
- Constants["CONFIG_VERSION"] = "1.3.13";
6435
+ Constants["CONFIG_VERSION"] = "1.3.15";
4925
6436
  /** Standard value for the first message's `parentMessageId` value, to indicate no parent exists. */
4926
6437
  Constants["NO_PARENT"] = "00000000-0000-0000-0000-000000000000";
4927
6438
  /** Standard value to use whatever the submission prelim. `responseMessageId` is */
@@ -4973,8 +6484,224 @@ let Constants = /* @__PURE__ */ function(Constants) {
4973
6484
  Constants["BASH_PROGRAMMATIC_TOOL_CALLING"] = "run_tools_with_bash";
4974
6485
  /** Subagent spawn tool name (must match `@librechat/agents` `Constants.SUBAGENT`). */
4975
6486
  Constants["SUBAGENT"] = "subagent";
6487
+ /** Poll tool for retrieving the status/result of a backgrounded tool call. */
6488
+ Constants["CHECK_BACKGROUND_TASK"] = "check_background_task";
6489
+ /**
6490
+ * `finish_reason` stamped on an assistant message whose turn ended because the
6491
+ * agent exhausted its per-turn graph step budget (`recursionLimit`) rather than
6492
+ * because the model chose to stop. Distinct from a user abort: nothing failed and
6493
+ * nothing was cancelled, the turn simply ran out of room. The UI keys its
6494
+ * "tool call limit reached" notice off this value. The hover Continue control
6495
+ * is withheld for this reason because the notice already offers the way forward.
6496
+ */
6497
+ Constants["TOOL_CALL_LIMIT_FINISH_REASON"] = "tool_call_limit";
4976
6498
  return Constants;
4977
6499
  }({});
6500
+ /**
6501
+ * Normalizes a server name into the character set tool keys are built from.
6502
+ * Tool keys embed this output, so any candidate list matched against a key must
6503
+ * be normalized the same way.
6504
+ */
6505
+ function normalizeServerName(serverName) {
6506
+ if (/^[a-zA-Z0-9_.-]+$/.test(serverName)) return serverName;
6507
+ const normalized = serverName.replace(/[^a-zA-Z0-9_.-]/g, "_").replace(/^_+|_+$/g, "");
6508
+ if (normalized) return normalized;
6509
+ /** All characters were stripped; hash the original so the name stays unique. */
6510
+ let hash = 0;
6511
+ for (let i = 0; i < serverName.length; i++) {
6512
+ hash = (hash << 5) - hash + serverName.charCodeAt(i);
6513
+ hash |= 0;
6514
+ }
6515
+ return `server_${Math.abs(hash)}`;
6516
+ }
6517
+ /**
6518
+ * Splits a combined MCP tool key (`${rawToolName}${mcp_delimiter}${serverName}`)
6519
+ * back into its two parts.
6520
+ *
6521
+ * Both halves can legitimately contain the delimiter, so position alone cannot
6522
+ * identify the boundary. Raw tool names come from the upstream server and are
6523
+ * untrusted (`get_mcp_server_version`, or a gateway-prefixed
6524
+ * `gitlab-get_mcp_server_version`), and `normalizeServerName` preserves
6525
+ * underscores, so a configured server may be named `Google_mcp_Workspace`.
6526
+ *
6527
+ * When `knownServerNames` is supplied the boundary is resolved against it: the
6528
+ * longest configured name the key actually ends with wins. Otherwise this falls
6529
+ * back to the last delimiter, which is correct whenever only the tool half
6530
+ * contains one and matches `.split()` when neither does.
6531
+ *
6532
+ * One case stays undecidable from the key alone: if both `bar` and `foo_mcp_bar`
6533
+ * are configured, `tool_mcp_foo_mcp_bar` is a valid key for either. Longest match
6534
+ * is the deterministic tiebreak; resolving it properly needs the tool/server
6535
+ * mapping carried alongside the key rather than re-derived from the string.
6536
+ */
6537
+ /**
6538
+ * Maps each configured server name's normalized form back to the raw config
6539
+ * name. Model-facing tool keys embed `normalizeServerName(server)`, while the
6540
+ * registry, config maps, tool cache, and plugin-auth rows are keyed by the raw
6541
+ * name — any consumer that parses a server out of a tool key must resolve it
6542
+ * through this map before those lookups. Identity entries are included so
6543
+ * `aliases.get(name) ?? name` works uniformly.
6544
+ *
6545
+ * When two configured names normalize to the same value their tool keys are
6546
+ * inherently ambiguous; the FIRST configured name wins deterministically here,
6547
+ * and `resolveMCPServerContext` warns about the collision so the operator can
6548
+ * rename one server.
6549
+ */
6550
+ function buildServerNameAliases(rawServerNames) {
6551
+ const aliases = /* @__PURE__ */ new Map();
6552
+ /** Identity entries claim their slot FIRST regardless of configuration
6553
+ * order: a server literally named `foo` must never have its keys rerouted
6554
+ * to a `foo!` whose normalized form collides with it. */
6555
+ for (const raw of rawServerNames) if (raw && normalizeServerName(raw) === raw) aliases.set(raw, raw);
6556
+ for (const raw of rawServerNames) {
6557
+ if (!raw) continue;
6558
+ const normalized = normalizeServerName(raw);
6559
+ if (!aliases.has(normalized)) aliases.set(normalized, raw);
6560
+ }
6561
+ return aliases;
6562
+ }
6563
+ /**
6564
+ * Rewrites a tool key's server segment into the normalized form model-facing
6565
+ * keys carry, resolving the boundary against the configured raw names (longest
6566
+ * suffix wins, mirroring {@link splitMCPToolKey}). Returns the key unchanged
6567
+ * when no configured raw name matches — already-normalized keys, placeholder
6568
+ * tokens, and keys for servers that are no longer configured all pass through.
6569
+ * Idempotent: a normalized segment never matches a raw candidate that needs
6570
+ * rewriting.
6571
+ */
6572
+ function normalizeMCPToolKey(toolKey, rawServerNames) {
6573
+ let matched;
6574
+ for (let i = 0; i < rawServerNames.length; i++) {
6575
+ const raw = rawServerNames[i];
6576
+ if (!raw || raw.length <= (matched?.length ?? 0)) continue;
6577
+ if (toolKey.endsWith(`_mcp_${raw}`)) matched = raw;
6578
+ }
6579
+ if (matched == null) return toolKey;
6580
+ const normalized = normalizeServerName(matched);
6581
+ if (normalized === matched) return toolKey;
6582
+ return `${toolKey.slice(0, toolKey.length - matched.length)}${normalized}`;
6583
+ }
6584
+ /**
6585
+ * Strips a redundant leading server-name prefix from a raw upstream tool name
6586
+ * before it is embedded into a model-facing key, so the key doesn't carry the
6587
+ * server twice (`acme_trace_..._mcp_acme`) and push long tool names
6588
+ * past provider function-name limits (64 chars). The match is case-insensitive
6589
+ * because display-cased server names ("Acme") conventionally prefix their
6590
+ * tools in lowercase. Ingestion that strips must record the original name
6591
+ * (`serverToolName` on the cached definition) — tool calls send THAT name back
6592
+ * to the server, never the stripped one. Catalog producers must not call this
6593
+ * directly: only {@link stripServerNamePrefixes} sees the whole sibling set and
6594
+ * can keep colliding results apart.
6595
+ */
6596
+ function stripServerNamePrefix(toolName, normalizedServerName) {
6597
+ const prefixLength = normalizedServerName.length + 1;
6598
+ if (toolName.length <= prefixLength) return toolName;
6599
+ if (toolName.slice(0, prefixLength).toLowerCase() !== `${normalizedServerName.toLowerCase()}_`) return toolName;
6600
+ const stripped = toolName.slice(prefixLength);
6601
+ if (isReservedMCPToolName(stripped)) return toolName;
6602
+ /** `isActionTool` classifies keys by the RELATIVE position of `_action_`
6603
+ * and `_mcp_`; stripping moves the first `_mcp_` earlier, so a server
6604
+ * whose normalized name contains `_action_` could see a real MCP tool
6605
+ * reclassified as an OpenAPI action (bypassing MCP authorization). Never
6606
+ * produce a key whose classification differs from the raw key's. */
6607
+ const keySuffix = `_mcp_${normalizedServerName}`;
6608
+ if (isActionTool(`${stripped}${keySuffix}`) !== isActionTool(`${toolName}${keySuffix}`)) return toolName;
6609
+ return stripped;
6610
+ }
6611
+ /**
6612
+ * Synthetic markers consumed by prefix (`isMCPAllPlaceholder`, the server-pin
6613
+ * skip, the client's OAuth stream classification), so each reserves BOTH its
6614
+ * exact name and its `${marker}${mcp_delimiter}` namespace: a stripped
6615
+ * remainder inside any of them would turn a real upstream tool into the
6616
+ * server-wide wildcard, the UI pin placeholder, or a synthetic OAuth call.
6617
+ */
6618
+ const RESERVED_MCP_TOOL_MARKERS = [
6619
+ `sys__all__sys`,
6620
+ `sys__server__sys`,
6621
+ "oauth"
6622
+ ];
6623
+ function isReservedMCPToolName(toolName) {
6624
+ /** `mcp_` opens the server-scoped pluginKey namespace (`mcp_${serverName}`),
6625
+ * and `lc_transfer_to_` opens the agent-handoff namespace (the client
6626
+ * renders such calls as handoffs; the background and intent passes exclude
6627
+ * them) — pre-strip tool keys could never enter either, since they always
6628
+ * began with the server name itself. */
6629
+ if (toolName.startsWith(`mcp_`) || toolName.startsWith(`lc_transfer_to_`)) return true;
6630
+ return RESERVED_MCP_TOOL_MARKERS.some((marker) => toolName === marker || toolName.startsWith(`${marker}_mcp_`));
6631
+ }
6632
+ /**
6633
+ * Maps every raw tool name in a server's catalog to its model-facing name,
6634
+ * stripping redundant server-name prefixes collision-free: when two names
6635
+ * yield the same result — a bare `foo` next to `<server>_foo`, or the
6636
+ * case-variant pair `<server>_Foo` / `<Server>_Foo` under the case-insensitive
6637
+ * prefix match — every collider keeps its raw name, so two distinct upstream
6638
+ * tools can never collapse onto one key. Unprefixed names count against the
6639
+ * result set through their identity mapping, which is what makes the bare-name
6640
+ * case fall out of the same counter.
6641
+ */
6642
+ function stripServerNamePrefixes(toolNames, normalizedServerName) {
6643
+ const rawNames = new Set(toolNames);
6644
+ const finalNames = new Map(toolNames.map((name) => {
6645
+ const stripped = stripServerNamePrefix(name, normalizedServerName);
6646
+ /** Every sibling's RAW name is reserved even when that sibling itself
6647
+ * strips away: keys persisted BEFORE stripping embed raw names, so a
6648
+ * stripped result landing on another sibling's raw name would route
6649
+ * that sibling's legacy references to the wrong upstream tool. */
6650
+ return [name, stripped !== name && rawNames.has(stripped) ? name : stripped];
6651
+ }));
6652
+ /** Reverting a collider to its raw name can itself collide with ANOTHER
6653
+ * sibling's stripped result (`foo` / `acme_foo` / `acme_acme_foo`), so the
6654
+ * guard iterates to a fixpoint. Each pass converts at least one stripped
6655
+ * result back to its unique raw name, so it terminates within the catalog
6656
+ * size. */
6657
+ let changed = true;
6658
+ while (changed) {
6659
+ changed = false;
6660
+ const counts = /* @__PURE__ */ new Map();
6661
+ finalNames.forEach((result) => {
6662
+ counts.set(result, (counts.get(result) ?? 0) + 1);
6663
+ });
6664
+ finalNames.forEach((result, raw) => {
6665
+ if (result !== raw && (counts.get(result) ?? 0) > 1) {
6666
+ finalNames.set(raw, raw);
6667
+ changed = true;
6668
+ }
6669
+ });
6670
+ }
6671
+ return finalNames;
6672
+ }
6673
+ function splitMCPToolKey(toolKey, knownServerNames) {
6674
+ if (knownServerNames?.length) {
6675
+ let matched;
6676
+ for (let i = 0; i < knownServerNames.length; i++) {
6677
+ const serverName = knownServerNames[i];
6678
+ if (!serverName || serverName.length <= (matched?.length ?? 0)) continue;
6679
+ if (toolKey.endsWith(`_mcp_${serverName}`)) matched = serverName;
6680
+ }
6681
+ if (matched != null) return [toolKey.slice(0, toolKey.length - matched.length - 5), matched];
6682
+ }
6683
+ const idx = toolKey.lastIndexOf("_mcp_");
6684
+ if (idx === -1) return [toolKey, void 0];
6685
+ return [toolKey.slice(0, idx), toolKey.slice(idx + 5)];
6686
+ }
6687
+ /**
6688
+ * Splits a tool-call name for display, where the key may be a synthetic MCP OAuth
6689
+ * call (`oauth${mcp_delimiter}${serverName}`) rather than a real tool key.
6690
+ *
6691
+ * A configured server name is authoritative when one matches, because a real tool key
6692
+ * always ends in its server. Only when none matches does the `oauth` prefix decide,
6693
+ * which keeps a genuine upstream tool named `oauth${mcp_delimiter}...` from being read
6694
+ * as a synthetic call while still resolving OAuth prompts for unconfigured servers.
6695
+ */
6696
+ function splitToolCallName(toolCallName, knownServerNames) {
6697
+ if (knownServerNames?.length) {
6698
+ const [toolName, serverName] = splitMCPToolKey(toolCallName, knownServerNames);
6699
+ if (serverName != null && knownServerNames.includes(serverName)) return [toolName, serverName];
6700
+ }
6701
+ const oauthPrefix = `oauth_mcp_`;
6702
+ if (toolCallName.startsWith(oauthPrefix)) return ["oauth", toolCallName.slice(oauthPrefix.length)];
6703
+ return splitMCPToolKey(toolCallName, knownServerNames);
6704
+ }
4978
6705
  /** Maximum explicit subagent hops allowed from any root agent at runtime. */
4979
6706
  const MAX_SUBAGENT_DEPTH = 5;
4980
6707
  /** Maximum unique explicit subagent targets that may be loaded at runtime. */
@@ -5026,6 +6753,8 @@ let LocalStorageKeys = /* @__PURE__ */ function(LocalStorageKeys) {
5026
6753
  LocalStorageKeys["LAST_ARTIFACTS_TOGGLE_"] = "LAST_ARTIFACTS_TOGGLE_";
5027
6754
  /** Last checked toggle for Skills per conversation ID */
5028
6755
  LocalStorageKeys["LAST_SKILLS_TOGGLE_"] = "LAST_SKILLS_TOGGLE_";
6756
+ /** Last checked toggle for Memory per conversation ID */
6757
+ LocalStorageKeys["LAST_MEMORY_TOGGLE_"] = "LAST_MEMORY_TOGGLE_";
5029
6758
  /** Key for the last selected agent provider */
5030
6759
  LocalStorageKeys["LAST_AGENT_PROVIDER"] = "lastAgentProvider";
5031
6760
  /** Key for the last selected agent model */
@@ -5160,6 +6889,7 @@ let PrincipalModel = /* @__PURE__ */ function(PrincipalModel) {
5160
6889
  */
5161
6890
  let ResourceType = /* @__PURE__ */ function(ResourceType) {
5162
6891
  ResourceType["AGENT"] = "agent";
6892
+ ResourceType["CODE_ENVIRONMENT"] = "codeEnvironment";
5163
6893
  ResourceType["PROMPTGROUP"] = "promptGroup";
5164
6894
  ResourceType["MCPSERVER"] = "mcpServer";
5165
6895
  ResourceType["REMOTE_AGENT"] = "remoteAgent";
@@ -5188,6 +6918,9 @@ let AccessRoleIds = /* @__PURE__ */ function(AccessRoleIds) {
5188
6918
  AccessRoleIds["AGENT_VIEWER"] = "agent_viewer";
5189
6919
  AccessRoleIds["AGENT_EDITOR"] = "agent_editor";
5190
6920
  AccessRoleIds["AGENT_OWNER"] = "agent_owner";
6921
+ AccessRoleIds["CODE_ENVIRONMENT_VIEWER"] = "codeEnvironment_viewer";
6922
+ AccessRoleIds["CODE_ENVIRONMENT_EDITOR"] = "codeEnvironment_editor";
6923
+ AccessRoleIds["CODE_ENVIRONMENT_OWNER"] = "codeEnvironment_owner";
5191
6924
  AccessRoleIds["PROMPTGROUP_VIEWER"] = "promptGroup_viewer";
5192
6925
  AccessRoleIds["PROMPTGROUP_EDITOR"] = "promptGroup_editor";
5193
6926
  AccessRoleIds["PROMPTGROUP_OWNER"] = "promptGroup_owner";
@@ -5304,17 +7037,20 @@ function permBitsToAccessLevel(permBits) {
5304
7037
  function accessRoleToPermBits(accessRoleId) {
5305
7038
  switch (accessRoleId) {
5306
7039
  case "agent_viewer":
7040
+ case "codeEnvironment_viewer":
5307
7041
  case "promptGroup_viewer":
5308
7042
  case "mcpServer_viewer":
5309
7043
  case "remoteAgent_viewer":
5310
7044
  case "skill_viewer":
5311
7045
  case "sharedLink_viewer": return 1;
5312
7046
  case "agent_editor":
7047
+ case "codeEnvironment_editor":
5313
7048
  case "promptGroup_editor":
5314
7049
  case "mcpServer_editor":
5315
7050
  case "remoteAgent_editor":
5316
7051
  case "skill_editor": return 3;
5317
7052
  case "agent_owner":
7053
+ case "codeEnvironment_owner":
5318
7054
  case "promptGroup_owner":
5319
7055
  case "mcpServer_owner":
5320
7056
  case "remoteAgent_owner":
@@ -5341,21 +7077,25 @@ let QueryKeys = /* @__PURE__ */ function(QueryKeys) {
5341
7077
  QueryKeys["sharedLinks"] = "sharedLinks";
5342
7078
  QueryKeys["allConversations"] = "allConversations";
5343
7079
  QueryKeys["archivedConversations"] = "archivedConversations";
7080
+ QueryKeys["pinnedConversations"] = "pinnedConversations";
5344
7081
  QueryKeys["searchConversations"] = "searchConversations";
5345
7082
  QueryKeys["conversation"] = "conversation";
5346
7083
  QueryKeys["searchEnabled"] = "searchEnabled";
7084
+ QueryKeys["langfuseConnection"] = "langfuseConnection";
7085
+ QueryKeys["langfuseSessionLink"] = "langfuseSessionLink";
5347
7086
  QueryKeys["user"] = "user";
5348
7087
  QueryKeys["name"] = "name";
5349
7088
  QueryKeys["models"] = "models";
5350
7089
  QueryKeys["balance"] = "balance";
5351
7090
  QueryKeys["endpoints"] = "endpoints";
5352
7091
  QueryKeys["tokenConfig"] = "tokenConfig";
5353
- QueryKeys["contextProjection"] = "contextProjection";
5354
7092
  QueryKeys["presets"] = "presets";
5355
7093
  QueryKeys["searchResults"] = "searchResults";
5356
7094
  QueryKeys["tokenCount"] = "tokenCount";
5357
7095
  QueryKeys["availablePlugins"] = "availablePlugins";
5358
7096
  QueryKeys["startupConfig"] = "startupConfig";
7097
+ QueryKeys["insights"] = "insights";
7098
+ QueryKeys["insightsAccess"] = "insightsAccess";
5359
7099
  QueryKeys["assistants"] = "assistants";
5360
7100
  QueryKeys["assistant"] = "assistant";
5361
7101
  QueryKeys["agents"] = "agents";
@@ -5410,17 +7150,29 @@ let QueryKeys = /* @__PURE__ */ function(QueryKeys) {
5410
7150
  QueryKeys["skillFileContent"] = "skillFileContent";
5411
7151
  QueryKeys["skillTree"] = "skillTree";
5412
7152
  QueryKeys["skillNodeContent"] = "skillNodeContent";
5413
- QueryKeys["skillFavorites"] = "skillFavorites";
7153
+ QueryKeys["toolFavorites"] = "toolFavorites";
5414
7154
  QueryKeys["skillStates"] = "skillStates";
5415
7155
  QueryKeys["favorites"] = "favorites";
7156
+ QueryKeys["schedules"] = "schedules";
7157
+ QueryKeys["schedule"] = "schedule";
7158
+ QueryKeys["parentSubagents"] = "parentSubagents";
7159
+ QueryKeys["subagentThread"] = "subagentThread";
7160
+ QueryKeys["codeEnvironments"] = "codeEnvironments";
7161
+ QueryKeys["agentQueuedTurns"] = "agentQueuedTurns";
5416
7162
  return QueryKeys;
5417
7163
  }({});
5418
7164
  const DynamicQueryKeys = { agentFiles: (agentId) => ["agentFiles", agentId] };
5419
7165
  let MutationKeys = /* @__PURE__ */ function(MutationKeys) {
7166
+ MutationKeys["subagentControl"] = "subagentControl";
7167
+ MutationKeys["enqueueAgentQueuedTurn"] = "enqueueAgentQueuedTurn";
7168
+ MutationKeys["cancelAgentQueuedTurn"] = "cancelAgentQueuedTurn";
7169
+ MutationKeys["updateLangfuseConnection"] = "updateLangfuseConnection";
7170
+ MutationKeys["testLangfuseConnection"] = "testLangfuseConnection";
5420
7171
  MutationKeys["createAgentApiKey"] = "createAgentApiKey";
5421
7172
  MutationKeys["deleteAgentApiKey"] = "deleteAgentApiKey";
5422
7173
  MutationKeys["fileUpload"] = "fileUpload";
5423
7174
  MutationKeys["fileDelete"] = "fileDelete";
7175
+ MutationKeys["fileUsage"] = "fileUsage";
5424
7176
  MutationKeys["updatePreset"] = "updatePreset";
5425
7177
  MutationKeys["deletePreset"] = "deletePreset";
5426
7178
  MutationKeys["loginUser"] = "loginUser";
@@ -5437,6 +7189,7 @@ let MutationKeys = /* @__PURE__ */ function(MutationKeys) {
5437
7189
  MutationKeys["deleteAgentAction"] = "deleteAgentAction";
5438
7190
  MutationKeys["revertAgentVersion"] = "revertAgentVersion";
5439
7191
  MutationKeys["deleteUser"] = "deleteUser";
7192
+ MutationKeys["updateUserPreferences"] = "updateUserPreferences";
5440
7193
  MutationKeys["updateRole"] = "updateRole";
5441
7194
  MutationKeys["enableTwoFactor"] = "enableTwoFactor";
5442
7195
  MutationKeys["verifyTwoFactor"] = "verifyTwoFactor";
@@ -5450,6 +7203,14 @@ let MutationKeys = /* @__PURE__ */ function(MutationKeys) {
5450
7203
  MutationKeys["deleteSkillNode"] = "deleteSkillNode";
5451
7204
  MutationKeys["updateSkillNodeContent"] = "updateSkillNodeContent";
5452
7205
  MutationKeys["convoPin"] = "convoPin";
7206
+ MutationKeys["archiveAllConversations"] = "archiveAllConversations";
7207
+ MutationKeys["createSchedule"] = "createSchedule";
7208
+ MutationKeys["updateSchedule"] = "updateSchedule";
7209
+ MutationKeys["deleteSchedule"] = "deleteSchedule";
7210
+ MutationKeys["runSchedule"] = "runSchedule";
7211
+ MutationKeys["pairCodeEnvironment"] = "pairCodeEnvironment";
7212
+ MutationKeys["updateCodeEnvironmentSettings"] = "updateCodeEnvironmentSettings";
7213
+ MutationKeys["deleteCodeEnvironment"] = "deleteCodeEnvironment";
5453
7214
  return MutationKeys;
5454
7215
  }({});
5455
7216
  //#endregion
@@ -5509,6 +7270,7 @@ const TOKEN_REFRESH_BUFFER_MS = 120 * 1e3;
5509
7270
  const refreshToken = (retry) => _post(refreshToken$1(retry));
5510
7271
  const SHARE_PAGE_PATH_REGEX = /^\/share\/[^/]+\/?$/;
5511
7272
  const SHARED_MESSAGES_PATH_REGEX = /^\/api\/share\/[^/]+$/;
7273
+ const SHARE_FORK_PATH_REGEX = /^\/api\/share\/[^/]+\/fork$/;
5512
7274
  const normalizePathname = (pathname) => pathname.startsWith("/") ? pathname : `/${pathname}`;
5513
7275
  const stripBasePath = (pathname) => {
5514
7276
  const normalizedPathname = normalizePathname(pathname);
@@ -5528,6 +7290,11 @@ const getRequestPathname = (url) => {
5528
7290
  }
5529
7291
  };
5530
7292
  const isSharedMessagesRequest = (url, method) => method?.toLowerCase() === "get" && SHARED_MESSAGES_PATH_REGEX.test(stripBasePath(getRequestPathname(url)));
7293
+ /** The "continue this chat" fork is a deliberate authenticated action initiated
7294
+ * from a share page, so it must reach auth recovery/redirect like the shared
7295
+ * data request — otherwise a logged-out (or cold-loaded) viewer's 401 is
7296
+ * rejected silently instead of routing them through login. */
7297
+ const isShareForkRequest = (url, method) => method?.toLowerCase() === "post" && SHARE_FORK_PATH_REGEX.test(stripBasePath(getRequestPathname(url)));
5531
7298
  const dispatchTokenUpdatedEvent = (token) => {
5532
7299
  setTokenHeader(token);
5533
7300
  clearAuthRedirectStartedAt();
@@ -5626,16 +7393,42 @@ const shouldRefreshBeforeRequest = (url) => {
5626
7393
  const timeUntilExpiry = expiresAt - Date.now();
5627
7394
  return timeUntilExpiry > 0 && timeUntilExpiry <= TOKEN_REFRESH_BUFFER_MS;
5628
7395
  };
7396
+ const refreshBeforeRequest = async (url) => {
7397
+ const state = getAuthRecoveryState();
7398
+ if (state.refreshPromise && !isAuthRecoveryEndpoint(url)) return state.refreshPromise.catch(() => null);
7399
+ if (!shouldRefreshBeforeRequest(url)) return null;
7400
+ return startAuthRecovery(false).catch(() => null);
7401
+ };
7402
+ const withAuthorization = (options, token) => {
7403
+ const headers = new Headers(options?.headers);
7404
+ if (token) headers.set("Authorization", `Bearer ${token}`);
7405
+ return {
7406
+ ...options,
7407
+ headers
7408
+ };
7409
+ };
7410
+ async function _authenticatedFetch(url, options) {
7411
+ if (typeof window === "undefined") return fetch(url, options);
7412
+ const token = await refreshBeforeRequest(url) ?? getBearerToken();
7413
+ const response = await fetch(url, withAuthorization(options, token));
7414
+ if (response.status !== 401 || isAuthRecoveryEndpoint(url) || isAuthRedirectInProgress() || !getBearerToken()) return response;
7415
+ let refreshedToken;
7416
+ try {
7417
+ refreshedToken = await startAuthRecovery(false);
7418
+ } catch {
7419
+ redirectToLoginOnce();
7420
+ return response;
7421
+ }
7422
+ if (!refreshedToken) {
7423
+ redirectToLoginOnce();
7424
+ return response;
7425
+ }
7426
+ await response.body?.cancel().catch(() => void 0);
7427
+ return fetch(url, withAuthorization(options, refreshedToken));
7428
+ }
5629
7429
  if (typeof window !== "undefined") {
5630
7430
  axios.interceptors.request.use(async (config) => {
5631
- const state = getAuthRecoveryState();
5632
- if (state.refreshPromise && !isAuthRecoveryEndpoint(config.url)) {
5633
- const token = await state.refreshPromise.catch(() => null);
5634
- if (token) setRequestAuthorizationHeader(config, token);
5635
- return config;
5636
- }
5637
- if (!shouldRefreshBeforeRequest(config.url)) return config;
5638
- const token = await startAuthRecovery(false).catch(() => null);
7431
+ const token = await refreshBeforeRequest(config.url);
5639
7432
  if (token) setRequestAuthorizationHeader(config, token);
5640
7433
  return config;
5641
7434
  });
@@ -5649,7 +7442,7 @@ if (typeof window !== "undefined") {
5649
7442
  /** Skip refresh when the Authorization header has been cleared (e.g. during logout),
5650
7443
  * but allow the shared link data request to proceed so private shares can still
5651
7444
  * recover auth/redirect without unrelated share-page queries forcing login. */
5652
- if (!axios.defaults.headers.common["Authorization"] && !(isSharePage() && isSharedMessagesRequest(originalRequest.url, originalRequest.method))) return Promise.reject(error);
7445
+ if (!axios.defaults.headers.common["Authorization"] && !(isSharePage() && (isSharedMessagesRequest(originalRequest.url, originalRequest.method) || isShareForkRequest(originalRequest.url, originalRequest.method)))) return Promise.reject(error);
5653
7446
  if (isAuthRedirectInProgress()) return Promise.reject(error);
5654
7447
  if (error.response.status === 401 && !originalRequest._retry) {
5655
7448
  if (!(getAuthRecoveryState().refreshPromise != null)) console.warn("401 error, refreshing token");
@@ -5662,8 +7455,12 @@ if (typeof window !== "undefined") {
5662
7455
  }
5663
7456
  redirectToLoginOnce();
5664
7457
  return Promise.reject(error);
5665
- } catch (err) {
5666
- return Promise.reject(err);
7458
+ } catch {
7459
+ /** A rejected refresh (stale/invalid session → 401/403) must route to
7460
+ * login just like an empty-token refresh, otherwise the original 401
7461
+ * surfaces to the caller (e.g. the share fork button) with no redirect. */
7462
+ redirectToLoginOnce();
7463
+ return Promise.reject(error);
5667
7464
  }
5668
7465
  }
5669
7466
  return Promise.reject(error);
@@ -5679,24 +7476,154 @@ var request_default = {
5679
7476
  delete: _delete,
5680
7477
  deleteWithOptions: _deleteWithOptions,
5681
7478
  patch: _patch,
7479
+ authenticatedFetch: _authenticatedFetch,
5682
7480
  refreshToken,
5683
7481
  dispatchTokenUpdatedEvent
5684
7482
  };
5685
7483
  //#endregion
7484
+ //#region src/upload.ts
7485
+ const EVENT_STREAM_MEDIA_TYPE = "text/event-stream";
7486
+ const HEARTBEAT_TIMEOUT_MS = 15e3;
7487
+ var FileUploadError = class extends Error {
7488
+ constructor(message, fileId, toolResource, displayToUser = false, code = 0) {
7489
+ super(message);
7490
+ this.name = "CustomAppError";
7491
+ this.code = code;
7492
+ this.file_id = fileId;
7493
+ this.tool_resource = toolResource;
7494
+ this.display_to_user = displayToUser;
7495
+ this.response = { data: { message: displayToUser ? message : "" } };
7496
+ }
7497
+ };
7498
+ var UploadCanceledError = class extends Error {
7499
+ constructor(..._args) {
7500
+ super(..._args);
7501
+ this.code = "ERR_CANCELED";
7502
+ }
7503
+ };
7504
+ const getFileId = (formData) => String(formData.get("file_id") ?? "");
7505
+ const getToolResource = (formData) => formData.get("tool_resource") ?? void 0;
7506
+ const parseEvent = (message) => {
7507
+ let type = "message";
7508
+ const data = [];
7509
+ for (const line of message.split(/\r?\n/)) {
7510
+ if (line.startsWith("event:")) {
7511
+ type = line.slice(6).trim();
7512
+ continue;
7513
+ }
7514
+ if (line.startsWith("data:")) data.push(line.slice(5).trimStart());
7515
+ }
7516
+ return {
7517
+ type,
7518
+ data: data.join("\n")
7519
+ };
7520
+ };
7521
+ const createHttpError = async (response, formData) => {
7522
+ let message = `Server responded with status: ${response.status}`;
7523
+ try {
7524
+ message = (await response.json()).message || message;
7525
+ } catch {}
7526
+ return new FileUploadError(message, getFileId(formData), getToolResource(formData), true, response.status);
7527
+ };
7528
+ const createStreamError = (data, formData) => {
7529
+ let error;
7530
+ try {
7531
+ error = JSON.parse(data);
7532
+ } catch {
7533
+ error = { message: data };
7534
+ }
7535
+ 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);
7536
+ };
7537
+ const readEventStream = async (stream, formData) => {
7538
+ const reader = stream.getReader();
7539
+ const decoder = new TextDecoder();
7540
+ let buffer = "";
7541
+ let result = null;
7542
+ let streamEnded = false;
7543
+ let timeoutError = null;
7544
+ let heartbeatTimer;
7545
+ const resetHeartbeatTimer = () => {
7546
+ clearTimeout(heartbeatTimer);
7547
+ heartbeatTimer = setTimeout(() => {
7548
+ timeoutError = /* @__PURE__ */ new Error("Upload connection timed out waiting for a heartbeat.");
7549
+ reader.cancel(timeoutError);
7550
+ }, HEARTBEAT_TIMEOUT_MS);
7551
+ };
7552
+ resetHeartbeatTimer();
7553
+ try {
7554
+ while (true) {
7555
+ const { value, done } = await reader.read();
7556
+ if (done) {
7557
+ streamEnded = true;
7558
+ if (timeoutError) throw timeoutError;
7559
+ if (result) return result;
7560
+ throw new Error("Upload connection closed before completion.");
7561
+ }
7562
+ buffer += decoder.decode(value, { stream: true });
7563
+ const messages = buffer.split(/\r?\n\r?\n/);
7564
+ buffer = messages.pop() ?? "";
7565
+ for (const message of messages) {
7566
+ const event = parseEvent(message);
7567
+ if (event.type === "heartbeat") {
7568
+ resetHeartbeatTimer();
7569
+ continue;
7570
+ }
7571
+ if (event.type === "error") throw createStreamError(event.data, formData);
7572
+ if (event.type === "data") {
7573
+ result = JSON.parse(event.data);
7574
+ continue;
7575
+ }
7576
+ if (event.type === "close") {
7577
+ if (result) return result;
7578
+ throw new Error("Upload stream closed without a result.");
7579
+ }
7580
+ }
7581
+ }
7582
+ } catch (error) {
7583
+ if (error instanceof Error && error.name === "AbortError") throw new UploadCanceledError("Upload canceled.");
7584
+ throw error;
7585
+ } finally {
7586
+ clearTimeout(heartbeatTimer);
7587
+ if (!streamEnded) await reader.cancel().catch(() => void 0);
7588
+ reader.releaseLock();
7589
+ }
7590
+ };
7591
+ async function uploadEventStream(url, formData, signal) {
7592
+ try {
7593
+ const response = await request_default.authenticatedFetch(url, {
7594
+ method: "POST",
7595
+ body: formData,
7596
+ headers: { Accept: EVENT_STREAM_MEDIA_TYPE },
7597
+ signal: signal ?? void 0
7598
+ });
7599
+ if (!response.ok) throw await createHttpError(response, formData);
7600
+ if (!(response.headers.get("Content-Type")?.toLowerCase() ?? "").includes(EVENT_STREAM_MEDIA_TYPE)) return await response.json();
7601
+ if (!response.body) throw new Error("No upload response body received.");
7602
+ return await readEventStream(response.body, formData);
7603
+ } catch (error) {
7604
+ if (signal?.aborted || error instanceof Error && error.name === "AbortError") throw new UploadCanceledError("Upload canceled.");
7605
+ throw error;
7606
+ }
7607
+ }
7608
+ //#endregion
5686
7609
  //#region src/data-service.ts
5687
7610
  var data_service_exports = /* @__PURE__ */ __exportAll({
5688
7611
  acceptTerms: () => acceptTerms,
5689
7612
  addPromptToGroup: () => addPromptToGroup,
5690
7613
  addTagToConversation: () => addTagToConversation,
7614
+ addToolFavorite: () => addToolFavorite,
7615
+ archiveAllConversations: () => archiveAllConversations,
5691
7616
  archiveConversation: () => archiveConversation,
5692
7617
  assignConversationToProject: () => assignConversationToProject,
5693
7618
  bindActionOAuth: () => bindActionOAuth,
5694
7619
  bindMCPOAuth: () => bindMCPOAuth,
5695
7620
  branchMessage: () => branchMessage,
5696
7621
  callTool: () => callTool,
7622
+ cancelAgentQueuedTurn: () => cancelAgentQueuedTurn,
5697
7623
  cancelMCPOAuth: () => cancelMCPOAuth,
5698
7624
  clearAllConversations: () => clearAllConversations,
5699
7625
  confirmTwoFactor: () => confirmTwoFactor,
7626
+ controlSubagentTask: () => controlSubagentTask,
5700
7627
  createAgent: () => createAgent,
5701
7628
  createAgentApiKey: () => createAgentApiKey,
5702
7629
  createAssistant: () => createAssistant,
@@ -5706,6 +7633,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5706
7633
  createPreset: () => createPreset,
5707
7634
  createProject: () => createProject,
5708
7635
  createPrompt: () => createPrompt,
7636
+ createSchedule: () => createSchedule,
5709
7637
  createSharedLink: () => createSharedLink,
5710
7638
  createSkill: () => createSkill,
5711
7639
  createSkillNode: () => createSkillNode,
@@ -5714,16 +7642,19 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5714
7642
  deleteAgentAction: () => deleteAgentAction,
5715
7643
  deleteAgentApiKey: () => deleteAgentApiKey,
5716
7644
  deleteAssistant: () => deleteAssistant,
7645
+ deleteCodeEnvironment: () => deleteCodeEnvironment,
5717
7646
  deleteConversation: () => deleteConversation,
5718
7647
  deleteConversationTag: () => deleteConversationTag,
5719
7648
  deleteFiles: () => deleteFiles,
5720
7649
  deleteGitHubSkillSyncCredential: () => deleteGitHubSkillSyncCredential,
5721
7650
  deleteMCPServer: () => deleteMCPServer,
5722
7651
  deleteMemory: () => deleteMemory,
7652
+ deleteMemoryById: () => deleteMemoryById,
5723
7653
  deletePreset: () => deletePreset,
5724
7654
  deleteProject: () => deleteProject,
5725
7655
  deletePrompt: () => deletePrompt,
5726
7656
  deletePromptGroup: () => deletePromptGroup,
7657
+ deleteSchedule: () => deleteSchedule,
5727
7658
  deleteSharedLink: () => deleteSharedLink,
5728
7659
  deleteSkill: () => deleteSkill,
5729
7660
  deleteSkillFile: () => deleteSkillFile,
@@ -5734,7 +7665,9 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5734
7665
  duplicateConversation: () => duplicateConversation,
5735
7666
  editArtifact: () => editArtifact,
5736
7667
  enableTwoFactor: () => enableTwoFactor,
7668
+ enqueueAgentQueuedTurn: () => enqueueAgentQueuedTurn,
5737
7669
  forkConversation: () => forkConversation,
7670
+ forkSharedConversation: () => forkSharedConversation,
5738
7671
  genTitle: () => genTitle,
5739
7672
  getAIEndpoints: () => getAIEndpoints,
5740
7673
  getAccessRoles: () => getAccessRoles,
@@ -5744,6 +7677,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5744
7677
  getAgentById: () => getAgentById,
5745
7678
  getAgentCategories: () => getAgentCategories,
5746
7679
  getAgentFiles: () => getAgentFiles,
7680
+ getAgentVersions: () => getAgentVersions,
5747
7681
  getAllEffectivePermissions: () => getAllEffectivePermissions,
5748
7682
  getAllPromptGroups: () => getAllPromptGroups,
5749
7683
  getAssistantById: () => getAssistantById,
@@ -5753,8 +7687,8 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5753
7687
  getAvailableTools: () => getAvailableTools,
5754
7688
  getBanner: () => getBanner,
5755
7689
  getCategories: () => getCategories,
7690
+ getCodeEnvironments: () => getCodeEnvironments,
5756
7691
  getCodeOutputDownload: () => getCodeOutputDownload,
5757
- getContextProjection: () => getContextProjection,
5758
7692
  getConversationById: () => getConversationById,
5759
7693
  getConversationTags: () => getConversationTags,
5760
7694
  getConversations: () => getConversations,
@@ -5770,17 +7704,24 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5770
7704
  getFiles: () => getFiles,
5771
7705
  getGitHubSkillSyncStatus: () => getGitHubSkillSyncStatus,
5772
7706
  getGraphApiToken: () => getGraphApiToken,
7707
+ getInsights: () => getInsights,
7708
+ getInsightsAccess: () => getInsightsAccess,
7709
+ getLangfuseConnection: () => getLangfuseConnection,
7710
+ getLangfuseSessionLink: () => getLangfuseSessionLink,
5773
7711
  getLoginGoogle: () => getLoginGoogle,
5774
7712
  getMCPAuthValues: () => getMCPAuthValues,
5775
7713
  getMCPConnectionStatus: () => getMCPConnectionStatus,
7714
+ getMCPOAuthStatus: () => getMCPOAuthStatus,
5776
7715
  getMCPServer: () => getMCPServer,
5777
7716
  getMCPServerConnectionStatus: () => getMCPServerConnectionStatus,
5778
7717
  getMCPServers: () => getMCPServers,
5779
7718
  getMCPTools: () => getMCPTools,
5780
7719
  getMarketplaceAgents: () => getMarketplaceAgents,
5781
7720
  getMemories: () => getMemories,
7721
+ getMessageById: () => getMessageById,
5782
7722
  getMessagesByConvoId: () => getMessagesByConvoId,
5783
7723
  getModels: () => getModels,
7724
+ getParentSubagents: () => getParentSubagents,
5784
7725
  getPresets: () => getPresets,
5785
7726
  getProjectById: () => getProjectById,
5786
7727
  getPrompt: () => getPrompt,
@@ -5790,6 +7731,8 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5790
7731
  getRandomPrompts: () => getRandomPrompts,
5791
7732
  getResourcePermissions: () => getResourcePermissions,
5792
7733
  getRole: () => getRole,
7734
+ getSchedule: () => getSchedule,
7735
+ getSchedules: () => getSchedules,
5793
7736
  getSearchEnabled: () => getSearchEnabled,
5794
7737
  getSharedFileDownload: () => getSharedFileDownload,
5795
7738
  getSharedFilePreview: () => getSharedFilePreview,
@@ -5797,14 +7740,15 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5797
7740
  getSharedMessages: () => getSharedMessages,
5798
7741
  getSharedStartupConfig: () => getSharedStartupConfig,
5799
7742
  getSkill: () => getSkill,
5800
- getSkillFavorites: () => getSkillFavorites,
5801
7743
  getSkillFileContent: () => getSkillFileContent,
5802
7744
  getSkillNodeContent: () => getSkillNodeContent,
5803
7745
  getSkillStates: () => getSkillStates,
5804
7746
  getSkillTree: () => getSkillTree,
5805
7747
  getStartupConfig: () => getStartupConfig,
7748
+ getSubagentThread: () => getSubagentThread,
5806
7749
  getTokenConfig: () => getTokenConfig,
5807
7750
  getToolCalls: () => getToolCalls,
7751
+ getToolFavorites: () => getToolFavorites,
5808
7752
  getUser: () => getUser,
5809
7753
  getUserBalance: () => getUserBalance,
5810
7754
  getUserTerms: () => getUserTerms,
@@ -5813,6 +7757,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5813
7757
  healthCheck: () => healthCheck,
5814
7758
  importConversationsFile: () => importConversationsFile,
5815
7759
  importSkill: () => importSkill,
7760
+ listAgentQueuedTurns: () => listAgentQueuedTurns,
5816
7761
  listAgents: () => listAgents,
5817
7762
  listAssistants: () => listAssistants,
5818
7763
  listConversations: () => listConversations,
@@ -5825,12 +7770,15 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5825
7770
  login: () => login,
5826
7771
  logout: () => logout,
5827
7772
  makePromptProduction: () => makePromptProduction,
7773
+ markFilesUsage: () => markFilesUsage,
7774
+ pairCodeEnvironment: () => pairCodeEnvironment,
5828
7775
  pinConversation: () => pinConversation,
5829
7776
  rebuildConversationTags: () => rebuildConversationTags,
5830
7777
  recordPromptGroupUsage: () => recordPromptGroupUsage,
5831
7778
  regenerateBackupCodes: () => regenerateBackupCodes,
5832
7779
  register: () => register,
5833
7780
  reinitializeMCPServer: () => reinitializeMCPServer,
7781
+ removeToolFavorite: () => removeToolFavorite,
5834
7782
  requestPasswordReset: () => requestPasswordReset,
5835
7783
  resendVerificationEmail: () => resendVerificationEmail,
5836
7784
  resetPassword: () => resetPassword,
@@ -5838,23 +7786,28 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5838
7786
  revokeAllUserKeys: () => revokeAllUserKeys,
5839
7787
  revokeUserKey: () => revokeUserKey,
5840
7788
  runGitHubSkillSync: () => runGitHubSkillSync,
7789
+ runScheduleNow: () => runScheduleNow,
5841
7790
  searchPrincipals: () => searchPrincipals,
5842
7791
  setGitHubSkillSyncCredential: () => setGitHubSkillSyncCredential,
5843
7792
  speechToText: () => speechToText,
7793
+ testLangfuseConnection: () => testLangfuseConnection,
5844
7794
  textToSpeech: () => textToSpeech,
5845
7795
  updateAction: () => updateAction,
5846
7796
  updateAgent: () => updateAgent,
5847
7797
  updateAgentAction: () => updateAgentAction,
5848
7798
  updateAgentPermissions: () => updateAgentPermissions,
5849
7799
  updateAssistant: () => updateAssistant,
7800
+ updateCodeEnvironmentSettings: () => updateCodeEnvironmentSettings,
5850
7801
  updateConversation: () => updateConversation,
5851
7802
  updateConversationTag: () => updateConversationTag,
5852
7803
  updateFavorites: () => updateFavorites,
5853
7804
  updateFeedback: () => updateFeedback,
7805
+ updateLangfuseConnection: () => updateLangfuseConnection,
5854
7806
  updateMCPServer: () => updateMCPServer,
5855
7807
  updateMCPServersPermissions: () => updateMCPServersPermissions,
5856
7808
  updateMarketplacePermissions: () => updateMarketplacePermissions,
5857
7809
  updateMemory: () => updateMemory,
7810
+ updateMemoryById: () => updateMemoryById,
5858
7811
  updateMemoryPermissions: () => updateMemoryPermissions,
5859
7812
  updateMemoryPreferences: () => updateMemoryPreferences,
5860
7813
  updateMessage: () => updateMessage,
@@ -5867,9 +7820,9 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5867
7820
  updatePromptPermissions: () => updatePromptPermissions,
5868
7821
  updateRemoteAgentsPermissions: () => updateRemoteAgentsPermissions,
5869
7822
  updateResourcePermissions: () => updateResourcePermissions,
7823
+ updateSchedule: () => updateSchedule,
5870
7824
  updateSharedLink: () => updateSharedLink,
5871
7825
  updateSkill: () => updateSkill,
5872
- updateSkillFavorites: () => updateSkillFavorites,
5873
7826
  updateSkillNode: () => updateSkillNode,
5874
7827
  updateSkillNodeContent: () => updateSkillNodeContent,
5875
7828
  updateSkillPermissions: () => updateSkillPermissions,
@@ -5877,6 +7830,7 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5877
7830
  updateTokenCount: () => updateTokenCount,
5878
7831
  updateUserKey: () => updateUserKey,
5879
7832
  updateUserPlugins: () => updateUserPlugins,
7833
+ updateUserPreferences: () => updateUserPreferences,
5880
7834
  uploadAgentAvatar: () => uploadAgentAvatar,
5881
7835
  uploadAssistantAvatar: () => uploadAssistantAvatar,
5882
7836
  uploadAvatar: () => uploadAvatar,
@@ -5888,6 +7842,27 @@ var data_service_exports = /* @__PURE__ */ __exportAll({
5888
7842
  verifyTwoFactor: () => verifyTwoFactor,
5889
7843
  verifyTwoFactorTemp: () => verifyTwoFactorTemp
5890
7844
  });
7845
+ function getInsights(params = {}) {
7846
+ const query = new URLSearchParams();
7847
+ for (const [key, value] of Object.entries(params)) if (value !== void 0 && value !== null && value !== "") query.set(key, String(value));
7848
+ const suffix = query.toString() ? `?${query.toString()}` : "";
7849
+ return request_default.get(`${insights()}${suffix}`);
7850
+ }
7851
+ function getInsightsAccess() {
7852
+ return request_default.get(insightsAccess());
7853
+ }
7854
+ function getLangfuseConnection() {
7855
+ return request_default.get(adminLangfuseConnection());
7856
+ }
7857
+ function updateLangfuseConnection(payload) {
7858
+ return request_default.put(adminLangfuseConnection(), payload);
7859
+ }
7860
+ function testLangfuseConnection(payload) {
7861
+ return request_default.post(adminLangfuseConnectionTest(), payload);
7862
+ }
7863
+ function getLangfuseSessionLink(conversationId) {
7864
+ return request_default.get(adminLangfuseSessionLink(conversationId));
7865
+ }
5891
7866
  function revokeUserKey(name) {
5892
7867
  return request_default.delete(revokeUserKey$1(name));
5893
7868
  }
@@ -5897,22 +7872,33 @@ function revokeAllUserKeys() {
5897
7872
  function deleteUser(payload) {
5898
7873
  return request_default.deleteWithOptions(deleteUser$1(), { data: payload });
5899
7874
  }
7875
+ function getCodeEnvironments() {
7876
+ return request_default.get(codeEnvironments());
7877
+ }
7878
+ function pairCodeEnvironment(payload) {
7879
+ return request_default.post(codeEnvironmentPairings(), payload);
7880
+ }
7881
+ function deleteCodeEnvironment(id) {
7882
+ return request_default.delete(codeEnvironmentById(id));
7883
+ }
7884
+ function updateCodeEnvironmentSettings({ id, settings }) {
7885
+ return request_default.patch(codeEnvironmentSettings(id), { settings });
7886
+ }
5900
7887
  function getFavorites() {
5901
7888
  return request_default.get(`${apiBaseUrl()}/api/user/settings/favorites`);
5902
7889
  }
5903
7890
  function updateFavorites(favorites) {
5904
7891
  return request_default.post(`${apiBaseUrl()}/api/user/settings/favorites`, { favorites });
5905
7892
  }
5906
- /**
5907
- * Skill favorites (star-a-skill). The backend route is phase 2 — see the
5908
- * original UI PR for the client surface. Until then, these resolve with
5909
- * an empty list so the UI hooks compile and the Star button is a no-op.
5910
- */
5911
- function getSkillFavorites() {
5912
- return Promise.resolve([]);
7893
+ /** Tool favorites — starred marketplace items (builtins, tools, MCP servers, skills). */
7894
+ function getToolFavorites() {
7895
+ return request_default.get(toolFavorites());
7896
+ }
7897
+ function addToolFavorite(favorite) {
7898
+ return request_default.put(toolFavorite(favorite.itemType, favorite.itemId));
5913
7899
  }
5914
- function updateSkillFavorites(skillFavorites) {
5915
- return Promise.resolve(skillFavorites);
7900
+ function removeToolFavorite(favorite) {
7901
+ return request_default.delete(toolFavorite(favorite.itemType, favorite.itemId));
5916
7902
  }
5917
7903
  /** Per-user skill active/inactive overrides. */
5918
7904
  function getSkillStates() {
@@ -5981,6 +7967,9 @@ function getSearchEnabled() {
5981
7967
  function getUser() {
5982
7968
  return request_default.get(user());
5983
7969
  }
7970
+ function updateUserPreferences(preferences) {
7971
+ return request_default.patch(userPreferences(), preferences);
7972
+ }
5984
7973
  function getUserBalance() {
5985
7974
  return request_default.get(balance());
5986
7975
  }
@@ -6039,6 +8028,9 @@ const getMCPAuthValues = (serverName) => {
6039
8028
  function cancelMCPOAuth(serverName) {
6040
8029
  return request_default.post(cancelMCPOAuth$1(serverName), {});
6041
8030
  }
8031
+ function getMCPOAuthStatus(flowId) {
8032
+ return request_default.get(mcpOAuthStatus(flowId));
8033
+ }
6042
8034
  const getStartupConfig = (options) => {
6043
8035
  return request_default.get(config(options?.context));
6044
8036
  };
@@ -6048,9 +8040,6 @@ const getAIEndpoints = () => {
6048
8040
  const getTokenConfig = () => {
6049
8041
  return request_default.get(tokenConfig());
6050
8042
  };
6051
- const getContextProjection = (payload) => {
6052
- return request_default.post(contextProjection(), payload);
6053
- };
6054
8043
  const getModels = async () => {
6055
8044
  return request_default.get(models());
6056
8045
  };
@@ -6150,14 +8139,24 @@ const getAgentFiles = (agentId) => {
6150
8139
  const getFileConfig = () => {
6151
8140
  return request_default.get(`${files()}/config`);
6152
8141
  };
6153
- const uploadImage = (data, signal) => {
8142
+ const uploadImage = (data, signal, sseEnabled = false) => {
6154
8143
  const requestConfig = signal ? { signal } : void 0;
8144
+ if (sseEnabled) return uploadEventStream(images(), data, signal);
6155
8145
  return request_default.postMultiPart(images(), data, requestConfig);
6156
8146
  };
6157
- const uploadFile = (data, signal) => {
8147
+ const uploadFile = (data, signal, sseEnabled = false) => {
6158
8148
  const requestConfig = signal ? { signal } : void 0;
8149
+ if (sseEnabled) return uploadEventStream(files(), data, signal);
6159
8150
  return request_default.postMultiPart(files(), data, requestConfig);
6160
8151
  };
8152
+ /**
8153
+ * Marks uploaded files as used (owner-scoped TTL touch) so the upload-window
8154
+ * TTL cannot reap attachments held in a client-side queue during a long run.
8155
+ * Best-effort: callers fire-and-forget — send-time marking is the backstop.
8156
+ */
8157
+ const markFilesUsage = (body) => {
8158
+ return request_default.post(fileUsage(), body);
8159
+ };
6161
8160
  const updateAction = (data) => {
6162
8161
  const { assistant_id, version, ...body } = data;
6163
8162
  return request_default.post(assistants({
@@ -6185,6 +8184,9 @@ const getAgentById = ({ agent_id }) => {
6185
8184
  const getExpandedAgentById = ({ agent_id }) => {
6186
8185
  return request_default.get(agents({ path: `${agent_id}/expanded` }));
6187
8186
  };
8187
+ const getAgentVersions = ({ agent_id }) => {
8188
+ return request_default.get(agents({ path: `${agent_id}/versions` }));
8189
+ };
6188
8190
  const updateAgent = ({ agent_id, data }) => {
6189
8191
  return request_default.patch(agents({ path: agent_id }), data);
6190
8192
  };
@@ -6319,6 +8321,12 @@ function duplicateConversation(payload) {
6319
8321
  function forkConversation(payload) {
6320
8322
  return request_default.post(forkConversation$1(), payload);
6321
8323
  }
8324
+ function forkSharedConversation(shareId, targetMessageIndex, shareRevision) {
8325
+ return request_default.post(forkSharedMessages(shareId), {
8326
+ targetMessageIndex,
8327
+ shareRevision
8328
+ });
8329
+ }
6322
8330
  function deleteConversation(payload) {
6323
8331
  return request_default.deleteWithOptions(deleteConversation$1(), { data: { arg: payload } });
6324
8332
  }
@@ -6340,6 +8348,9 @@ function updateConversation(payload) {
6340
8348
  function archiveConversation(payload) {
6341
8349
  return request_default.post(archiveConversation$1(), { arg: payload });
6342
8350
  }
8351
+ function archiveAllConversations() {
8352
+ return request_default.post(archiveAllConversations$1(), {});
8353
+ }
6343
8354
  function listProjects(params) {
6344
8355
  return request_default.get(projects(params ?? {}));
6345
8356
  }
@@ -6398,6 +8409,21 @@ function getMessagesByConvoId(conversationId) {
6398
8409
  if (conversationId === "new" || conversationId === "PENDING") return Promise.resolve([]);
6399
8410
  return request_default.get(messages({ conversationId }));
6400
8411
  }
8412
+ function getMessageById(conversationId, messageId) {
8413
+ return request_default.get(messages({
8414
+ conversationId,
8415
+ messageId
8416
+ }));
8417
+ }
8418
+ function getParentSubagents(parentConversationId) {
8419
+ return request_default.get(parentSubagents(parentConversationId));
8420
+ }
8421
+ function getSubagentThread(parentConversationId, threadId, taskId, cursor) {
8422
+ return request_default.get(subagentThread(parentConversationId, threadId, taskId, cursor));
8423
+ }
8424
+ function controlSubagentTask(parentConversationId, threadId, body) {
8425
+ return request_default.post(subagentControl(parentConversationId, threadId), body);
8426
+ }
6401
8427
  function getPrompt(id) {
6402
8428
  return request_default.get(getPrompt$1(id));
6403
8429
  }
@@ -6446,6 +8472,33 @@ function getRandomPrompts(variables) {
6446
8472
  function listSkills(params) {
6447
8473
  return request_default.get(listSkillsWithFilters(params ?? {}));
6448
8474
  }
8475
+ function getSchedules() {
8476
+ return request_default.get(schedules());
8477
+ }
8478
+ function enqueueAgentQueuedTurn(payload) {
8479
+ return request_default.post(agentQueuedTurns(), payload);
8480
+ }
8481
+ function listAgentQueuedTurns(conversationId, clientRequestIds) {
8482
+ return request_default.get(agentQueuedTurnsByConversation(conversationId, clientRequestIds));
8483
+ }
8484
+ function cancelAgentQueuedTurn(queuedTurnId) {
8485
+ return request_default.delete(agentQueuedTurn(queuedTurnId));
8486
+ }
8487
+ function getSchedule(id) {
8488
+ return request_default.get(schedule(id));
8489
+ }
8490
+ function createSchedule(payload) {
8491
+ return request_default.post(schedules(), payload);
8492
+ }
8493
+ function updateSchedule(id, payload) {
8494
+ return request_default.patch(schedule(id), payload);
8495
+ }
8496
+ function deleteSchedule(id) {
8497
+ return request_default.delete(schedule(id));
8498
+ }
8499
+ function runScheduleNow(id) {
8500
+ return request_default.post(runSchedule(id), {});
8501
+ }
6449
8502
  function getSkill(id) {
6450
8503
  return request_default.get(getSkill$1(id));
6451
8504
  }
@@ -6633,15 +8686,24 @@ function verifyTwoFactorTemp(payload) {
6633
8686
  const getMemories = () => {
6634
8687
  return request_default.get(memories());
6635
8688
  };
6636
- const deleteMemory = (key) => {
6637
- return request_default.delete(memory(key));
8689
+ const deleteMemory = (key, agentId) => {
8690
+ return request_default.delete(memory(key, agentId));
6638
8691
  };
6639
- const updateMemory = (key, value, originalKey) => {
6640
- return request_default.patch(memory(originalKey || key), {
8692
+ const deleteMemoryById = (id, agentId) => {
8693
+ return request_default.delete(memoryById(id, agentId));
8694
+ };
8695
+ const updateMemory = (key, value, originalKey, agentId) => {
8696
+ return request_default.patch(memory(originalKey || key, agentId), {
6641
8697
  key,
6642
8698
  value
6643
8699
  });
6644
8700
  };
8701
+ const updateMemoryById = (id, value, key, agentId) => {
8702
+ return request_default.patch(memoryById(id, agentId), {
8703
+ value,
8704
+ ...key ? { key } : {}
8705
+ });
8706
+ };
6645
8707
  const updateMemoryPreferences = (preferences) => {
6646
8708
  return request_default.patch(memoryPreferences(), preferences);
6647
8709
  };
@@ -6676,6 +8738,6 @@ const getActiveJobs = () => {
6676
8738
  return request_default.get(activeJobs());
6677
8739
  };
6678
8740
  //#endregion
6679
- export { permissionEntrySchema as $, feedbackSchema as $a, extendedModelEndpointSchema as $i, MCP_USER_INPUT_FIELDS as $n, specsConfigSchema as $r, balanceSchema as $t, updateResourcePermissions as A, tPluginAuthConfigSchema as Aa, anthropicSettings as Ai, modularEndpoints as An, fileConfig as Ar, SKILL_SYNC_MAX_INTERVAL_MINUTES as At, MutationKeys as B, RunStatus as Ba, defaultAssistantFormValues as Bi, summarizationTriggerSchema as Bn, mbToBytes as Br, TTSProviders as Bt, resetPassword as C, tBannerSchema as Ca, ThinkingLevel as Ci, initialModelsConfig as Cn, defaultOCRMimeTypes as Cr, MAX_SUBAGENT_RUN_CONFIGS as Ct, updateFeedback as D, tExampleSchema as Da, agentsSettings as Di, messageFilterPiiSchema as Dn, endpointFileConfigSchema as Dr, RetentionMode as Dt, searchPrincipals as E, tConvoUpdateSchema as Ea, agentsSchema as Ei, memorySchema as En, documentParserMimeTypes as Er, RerankerTypes as Et, request_default as F, AnnotationTypes as Fa, compactAgentsBaseSchema as Fi, resolveEndpointType as Fn, imageMimeTypes as Fr, SearchCategories as Ft, PrincipalType as G, defaultOrderQuery as Ga, eReasoningEffortSchema as Gi, validateVisionModel as Gn, retrievalMimeTypesList as Gr, allowedAddressesSchema as Gt, AccessRoleIds as H, Tools as Ha, eAnthropicEffortSchema as Hi, transactionsSchema as Hn, mergeFileConfig as Hr, ViolationTypes as Ht, getTokenHeader as I, AssistantStreamEvents as Ia, compactAgentsSchema as Ii, skillSyncConfigSchema as In, imageTypeMapping as Ir, SearchProviders as It, accessRoleToPermBits as J, isActionTool as Ja, eReasoningSummarySchema as Ji, visionModels as Jn, textMimeTypes as Jr, assistantEndpointSchema as Jt, ResourceType as K, hostImageIdSuffix as Ka, eReasoningParameterFormatSchema as Ki, vertexAISchema as Kn, supportedMimeTypes as Kr, alternateName as Kt, setAcceptLanguageHeader as L, EToolResources as La, compactAssistantSchema as Li, skillSyncGitHubSourceSchema as Ln, inferMimeType as Lr, SettingsTabValues as Lt, updateUserKey as M, tPresetSchema as Ma, authTypeSchema as Mi, paramDefinitionSchema as Mn, fullMimeTypesList as Mr, STTProviders as Mt, updateUserPlugins as N, tQueryParamsSchema as Na, cacheSubsetProviders as Ni, providerEndpointMap as Nn, getEndpointFileConfig as Nr, SafeSearchTypes as Nt, updateMessage as O, tMessageSchema as Oa, anthropicBaseSchema as Oi, messageFilterSchema as On, excelFileTypes as Or, SKILL_SYNC_DEFAULT_DISCOVERY_DEPTH as Ot, userKeyQuery as P, tSharedLinkSchema as Pa, coerceNumber as Pi, rateLimitSchema as Pn, imageExtRegex as Pr, ScraperProviders as Pt, permBitsToAccessLevel as Q, feedbackRatingSchema as Qa, endpointSettings as Qi, MCPServersSchema as Qn, modelSpecSubagentsSchema as Qr, azureGroupSchema as Qt, setTokenHeader as R, FilePurpose as Ra, compactGoogleSchema as Ri, specialVariables as Rn, isBedrockDocumentType as Rr, SettingsViews as Rt, requestPasswordReset as S, removeNullishValues as Sa, ThinkingDisplay as Si, imageGenTools as Sn, convertStringsToRegex as Sr, MAX_SUBAGENT_GRAPH_NODES as St, revokeUserKey as T, tConversationTagSchema as Ta, agentsBaseSchema as Ti, isRemoteOidcUrlAllowed as Tn, defaultTextMimeTypes as Tr, RateLimitPrefix as Tt, PermissionBits as U, actionDelimiter as Ua, eImageDetailSchema as Ui, turnstileOptionsSchema as Un, mimeTypeAliases as Ur, VisionModes as Ut, QueryKeys as V, StepStatus as Va, documentSupportedProviders as Vi, supportsBalanceCheck as Vn, megabyte as Vr, Time as Vt, PrincipalModel as W, actionDomainSeparator as Wa, eModelEndpointSchema as Wi, turnstileSchema as Wn, retrievalMimeTypes as Wr, agentsEndpointSchema as Wt, getResourcePermissionsResponseSchema as X, FEEDBACK_REASON_KEYS as Xa, eThinkingLevelSchema as Xi, MCPOptionsSchema as Xn, REFILL_INTERVAL_UNITS as Xr, azureEndpointSchema as Xt, effectivePermissionsResponseSchema as Y, FEEDBACK_RATINGS as Ya, eThinkingDisplaySchema as Yi, webSearchSchema as Yn, videoMimeTypes as Yr, azureBaseSchema as Yt, hasPermissions as Z, FEEDBACK_TAGS as Za, eVerbositySchema as Zi, MCPServerUserInputSchema as Zn, getRefillEligibilityDate as Zr, azureGroupConfigsSchema as Zt, getResourcePermissions as _, openAIBaseSchema as _a, Providers as _i, fileStrategiesSchema as _n, bedrockDocumentExtensions as _r, ImageDetailCost as _t, data_service_exports as a, googleSettings as aa, generateDynamicSchema as ai, configSchema as an, extractEnvVariable as ao, AuthorizationTypeEnum as ar, AuthKeys as at, register as b, openRouterSchema as ba, ReasoningResponseKey as bi, getEndpointField as bn, codeInterpreterMimeTypesList as br, LocalStorageKeys as bt, getAccessRoles as c, inputTokensIncludesCache as ca, validateSettingDefinitions as ci, defaultAssistantsVersion as cn, normalizeEndpointName as co, FileSources as cr, Capabilities as ct, getAvailablePlugins as d, isDocumentSupportedProvider as da, BedrockProviders as di, defaultRetrievalModels as dn, buildLoginRedirectUrl as dr, DEFAULT_MEMORY_MAX_INPUT_TOKENS as dt, getModelKey as ea, tModelSpecSchema as ei, baseEndpointSchema as en, feedbackTagKeySchema as eo, SSEOptionsSchema as er, principalSchema as et, getConversationById as f, isImageVisionTool as fa, BedrockReasoningConfig as fi, defaultSocialLogins as fn, loginPage as fr, EImageOutputType as ft, getModels as g, isUUID as ga, MYTHOS_CLASS_FAMILIES as gi, fileStorageSchema as gn, audioMimeTypes as gr, ForkOptions as gt, getMCPServerConnectionStatus as h, isParamEndpoint as ha, ImageVisionTool as hi, fileSourceSchema as hn, applicationMimeTypes as hr, FetchTokenConfig as ht, createPreset as i, googleSchema as ia, SettingTypes as ii, cloudfrontConfigSchema as in, envVarRegex as io, AuthTypeEnum as ir, AgentCapabilities as it, updateTokenCount as j, tPluginSchema as ja, assistantSchema as ji, ocrSchema as jn, fileConfigSchema as jr, SKILL_SYNC_MIN_INTERVAL_MINUTES as jt, updateMessageContent as k, tModelSpecPresetSchema as ka, anthropicSchema as ki, modelConfigSchema as kn, excelMimeTypes as kr, SKILL_SYNC_MAX_DISCOVERY_DEPTH as kt, getAgentApiKeys as l, isAgentsEndpoint as la, AnthropicEffort as li, defaultEndpoints as ln, checkOpenAIStorage as lr, CohereConstants as lt, getEffectivePermissions as m, isOpenAILikeProvider as ma, ImageDetail as mi, excludedKeys as mn, sharedFileDownload as mr, ErrorTypes as mt, clearAllConversations as n, googleBaseSchema as na, ComponentTypes as ni, bedrockGuardrailConfigSchema as nn, getTagsForRating as no, StreamableHTTPOptionsSchema as nr, updateResourcePermissionsRequestSchema as nt, deleteAgentApiKey as o, imageDetailNumeric as oa, generateGoogleSchema as oi, contextPruningSchema as on, extractVariableName as oo, TokenExchangeMethodEnum as or, BASE_ONLY_CONFIG_SECTIONS as ot, getCustomConfigSpeech as p, isMythosClassModel as pa, EModelEndpoint as pi, endpointSchema as pn, registerPage as pr, EndpointURLs as pt, accessRoleSchema as q, hostImageNamePrefix as qa, eReasoningResponseKeySchema as qi, vertexModelConfigSchema as qn, supportsFiles as qr, anthropicEndpointSchema as qt, createAgentApiKey as r, googleGenConfigSchema as ra, OptionTypes as ri, bedrockModels as rn, toMinimalFeedback as ro, WebSocketOptionsSchema as rr, updateResourcePermissionsResponseSchema as rt, deletePreset as s, imageDetailValue as sa, generateOpenAISchema as si, defaultAgentCapabilities as sn, isSensitiveEnvVar as so, FileContext as sr, CacheKeys as st, cancelMCPOAuth as t, getSettingsKeys as ta, MAX_SUBAGENTS as ti, bedrockEndpointSchema as tn, getTagByKey as to, StdioOptionsSchema as tr, resourcePermissionsResponseSchema as tt, getAllEffectivePermissions as u, isAssistantsEndpoint as ua, AuthType as ui, defaultModels as un, apiBaseUrl as ur, Constants as ut, getSharedLink as v, openAISchema as va, ReasoningEffort as vi, getConfigDefaults as vn, bedrockDocumentFormats as vr, InfiniteCollections as vt, revokeAllUserKeys as w, tConversationSchema as wa, Verbosity as wi, interfaceSchema as wn, defaultSTTMimeTypes as wr, OCRStrategy as wt, reinitializeMCPServer as x, paramEndpoints as xa, ReasoningSummary as xi, getSchemaDefaults as xn, codeTypeMapping as xr, MAX_SUBAGENT_DEPTH as xt, getSharedMessages as y, openAISettings as ya, ReasoningParameterFormat as yi, getDefaultParamsEndpoint as yn, codeInterpreterMimeTypes as yr, KnownEndpoints as yt, DynamicQueryKeys as z, MessageContentTypes as za, defaultAgentFormValues as zi, summarizationConfigSchema as zn, isPermissiveMimeConfig as zr, SystemCategories as zt };
8741
+ export { permissionEntrySchema as $, googleSchema as $a, BedrockReasoningConfig as $i, specialVariables as $n, feedbackSchema as $o, defaultTextMimeTypes as $r, normalizeEndpointName as $s, azureGroupConfigsSchema as $t, updateResourcePermissions as A, defaultAgentFormValues as Aa, materializeModelSpecEndpoints as Ai, imageGenTools as An, tQueryParamsSchema as Ao, isProcessMCPServerField as Ar, feedbackFilterFieldSchema as As, SKILL_SYNC_DEFAULT_DISCOVERY_DEPTH as At, MutationKeys as B, eReasoningResponseKeySchema as Ba, getMaxSubagents as Bi, modularEndpoints as Bn, actionDelimiter as Bo, registerPage as Br, hasActivePiiPatterns as Bs, SettingsViews as Bt, resetPassword as C, authTypeSchema as Ca, setFileConfigRegexCompiler as Ci, fileSourceSchema as Cn, tConvoUpdateSchema as Co, MCP_USER_INPUT_FIELDS as Cr, SKILL_FILTER_FIELDS as Cs, MAX_SUBAGENT_DEPTH as Ct, updateFeedback as D, compactAgentsSchema as Da, videoMimeTypes as Di, getDefaultParamsEndpoint as Dn, tPluginAuthConfigSchema as Do, WebSocketOptionsSchema as Dr, agentInstructionFilterFieldSchema as Ds, RateLimitPrefix as Dt, searchPrincipals as E, compactAgentsBaseSchema as Ea, textMimeTypes as Ei, getConfigDefaults as En, tModelSpecPresetSchema as Eo, StreamableHTTPOptionsSchema as Er, actionMetadataFilterFieldSchema as Es, OCRStrategy as Et, request_default as F, eModelEndpointSchema as Fa, MAX_CHAT_PROJECT_DESCRIPTION_LENGTH as Fi, langfuseConfigSchema as Fn, FilePurpose as Fo, FileSources as Fr, filterPiiStarterPatternSchema as Fs, SafeSearchTypes as Ft, PrincipalType as G, endpointSettings as Ga, clampSettingRange as Gi, paramDefinitionSchema as Gn, isActionTool as Go, bedrockDocumentFormats as Gr, skillFilterFieldSchema as Gs, VisionModes as Gt, AccessRoleIds as H, eThinkingDisplaySchema as Ha, ComponentTypes as Hi, normalizeSearxngEngines as Hn, defaultOrderQuery as Ho, applicationMimeTypes as Hr, messageFilterFieldSchema as Hs, TTSProviders as Ht, getTokenHeader as I, eReasoningContextSchema as Ia, MAX_CHAT_PROJECT_NAME_LENGTH as Ii, memorySchema as In, MessageContentTypes as Io, checkOpenAIStorage as Ir, filtersConfigSchema as Is, ScraperProviders as It, accessRoleToPermBits as J, getGoogleThinkingBudgetMax as Ja, generateOpenAISchema as Ji, resolveEndpointType as Jn, resolveStatefulCodeEnvironment as Jo, codeInterpreterMimeTypesList as Jr, userSubmittedMessageFieldPathSchema as Js, alternateName as Jt, ResourceType as K, extendedModelEndpointSchema as Ka, generateDynamicSchema as Ki, providerEndpointMap as Kn, STATEFUL_CODE_ENVIRONMENTS as Ko, bedrockDocumentMimeTypes as Kr, toolArgumentFilterFieldSchema as Ks, agentsEndpointSchema as Kt, setAcceptLanguageHeader as L, eReasoningEffortSchema as La, MAX_GRAPH_SUBAGENT_MEMBERS as Li, messageFilterPiiSchema as Ln, RunStatus as Lo, apiBaseUrl as Lr, getPiiRegexProgramSize as Ls, SearchCategories as Lt, updateUserKey as M, documentSupportedProviders as Ma, resolveModelSpecEndpoint as Mi, interfaceSchema as Mn, AnnotationTypes as Mo, AuthorizationTypeEnum as Mr, filterPiiActionSchema as Ms, SKILL_SYNC_MAX_INTERVAL_MINUTES as Mt, updateUserPlugins as N, eAnthropicEffortSchema as Na, specsConfigSchema as Ni, isRemoteOidcUrlAllowed as Nn, AssistantStreamEvents as No, TokenExchangeMethodEnum as Nr, filterPiiCustomPatternSchema as Ns, SKILL_SYNC_MIN_INTERVAL_MINUTES as Nt, updateMessage as O, compactAssistantSchema as Oa, REFILL_INTERVAL_UNITS as Oi, getEndpointField as On, tPluginSchema as Oo, hasProcessMCPServerConfig as Or, conversationStarterFilterFieldSchema as Os, RerankerTypes as Ot, userKeyQuery as P, eImageDetailSchema as Pa, tModelSpecSchema as Pi, isSecureCodeEnvironmentControlURL as Pn, EToolResources as Po, FileContext as Pr, filterPiiRegexSchema as Ps, STTProviders as Pt, permBitsToAccessLevel as Q, googleGenConfigSchema as Qa, BedrockProviders as Qi, skillSyncGitHubSourceSchema as Qn, feedbackRatingSchema as Qo, defaultSTTMimeTypes as Qr, isSensitiveEnvVar as Qs, azureEndpointSchema as Qt, setTokenHeader as R, eReasoningModeSchema as Ra, MAX_SUBAGENTS as Ri, messageFilterSchema as Rn, StepStatus as Ro, buildLoginRedirectUrl as Rr, hasActiveFiltersConfig as Rs, SearchProviders as Rt, requestPasswordReset as S, assistantSchema as Sa, retrievalMimeTypesList as Si, excludedKeys as Sn, tConversationTagSchema as So, MCP_SERVER_TITLE_PATTERN as Sr, PROMPT_FILTER_FIELDS as Ss, LocalStorageKeys as St, revokeUserKey as T, coerceNumber as Ta, supportsFiles as Ti, fileStrategiesSchema as Tn, tMessageSchema as To, StdioOptionsSchema as Tr, TOOL_ARGUMENT_FILTER_FIELDS as Ts, MAX_SUBAGENT_RUN_CONFIGS as Tt, PermissionBits as U, eThinkingLevelSchema as Ua, OptionTypes as Ui, normalizeServerName as Un, hostImageIdSuffix as Uo, audioMimeTypes as Ur, modelParameterFilterFieldSchema as Us, Time as Ut, QueryKeys as V, eReasoningSummarySchema as Va, setMaxSubagents as Vi, normalizeMCPToolKey as Vn, actionDomainSeparator as Vo, sharedFileDownload as Vr, memoryFilterFieldSchema as Vs, SystemCategories as Vt, PrincipalModel as W, eVerbositySchema as Wa, SettingTypes as Wi, ocrSchema as Wn, hostImageNamePrefix as Wo, bedrockDocumentExtensions as Wr, promptFilterFieldSchema as Ws, ViolationTypes as Wt, getResourcePermissionsResponseSchema as X, getSettingsKeys as Xa, AnthropicEffort as Xi, setMessageFilterRegexValidator as Xn, FEEDBACK_REASON_KEYS as Xo, convertStringsToRegex as Xr, extractEnvVariable as Xs, assistantEndpointSchema as Xt, effectivePermissionsResponseSchema as Y, getModelKey as Ya, validateSettingDefinitions as Yi, retainRecentConfigSchema as Yn, FEEDBACK_RATINGS as Yo, codeTypeMapping as Yr, envVarRegex as Ys, anthropicEndpointSchema as Yt, hasPermissions as Z, googleBaseSchema as Za, AuthType as Zi, skillSyncConfigSchema as Zn, FEEDBACK_TAGS as Zo, defaultOCRMimeTypes as Zr, extractVariableName as Zs, azureBaseSchema as Zt, getResourcePermissions as _, agentsSchema as _a, mbToBytes as _i, defaultEndpoints as _n, removeNullishValues as _o, webSearchSchema as _r, MAX_PII_PATTERN_LABEL_LENGTH as _s, FetchTokenConfig as _t, data_service_exports as a, Providers as aa, fileConfigSchema as ai, bedrockModels as an, isAssistantsEndpoint as ao, summarizationTriggerSchema as ar, AGENT_INSTRUCTION_FILTER_FIELDS as as, AgentCapabilities as at, register as b, anthropicSchema as ba, mimeTypeAliases as bi, defaultSocialLogins as bn, tBannerSchema as bo, MCPServersSchema as br, MESSAGE_FILTER_FIELDS as bs, InfiniteCollections as bt, getAccessRoles as c, ReasoningMode as ca, getEndpointFileConfig as ci, checkpointerTypeSchema as cn, isMythosClassModel as co, toolApprovalModeSchema as cr, FEEDBACK_FILTER_FIELDS as cs, BASE_PRINCIPAL_CONFIG_SECTIONS as ct, getAvailablePlugins as d, ReasoningSummary as da, imageTypeMapping as di, codeEnvironmentUserConfigSchema as dn, isUUID as do, turnstileOptionsSchema as dr, HITL_MESSAGE_FILTER_FIELDS as ds, CohereConstants as dt, EModelEndpoint as ea, documentParserMimeTypes as ei, azureGroupSchema as en, googleSettings as eo, splitMCPToolKey as er, feedbackTagKeySchema as es, principalSchema as et, getConversationById as f, SkillsScope as fa, inferMimeType as fi, codeEnvironmentUserSettingsSchema as fn, openAIBaseSchema as fo, turnstileSchema as fr, MAX_PII_CUSTOM_PATTERNS_TOTAL as fs, Constants as ft, getModels as g, agentsBaseSchema as ga, isPermissiveMimeConfig as gi, defaultAssistantsVersion as gn, paramEndpoints as go, visionModels as gr, MAX_PII_PATTERN_ID_LENGTH as gs, ErrorTypes as gt, getMCPServerConnectionStatus as h, Verbosity as ha, isBedrockDocumentType as hi, defaultAgentCapabilities as hn, openRouterSchema as ho, vertexModelConfigSchema as hr, MAX_PII_PATTERNS_PER_SOURCE as hs, EndpointURLs as ht, createPreset as i, MemoryScope as ia, fileConfig as ii, bedrockGuardrailConfigSchema as in, isAgentsEndpoint as io, summarizationConfigSchema as ir, ACTION_METADATA_FILTER_FIELDS as is, AUTH_USER_DOC_BY_ID_PREFIX as it, updateTokenCount as j, defaultAssistantFormValues as ja, modelSpecSubagentsSchema as ji, initialModelsConfig as jn, tSharedLinkSchema as jo, AuthTypeEnum as jr, fileFilterFieldSchema as js, SKILL_SYNC_MAX_DISCOVERY_DEPTH as jt, updateMessageContent as k, compactGoogleSchema as ka, getRefillEligibilityDate as ki, getSchemaDefaults as kn, tPresetSchema as ko, isProcessMCPServerConfig as kr, conversationTitleFilterFieldSchema as ks, RetentionMode as kt, getAgentApiKeys as l, ReasoningParameterFormat as la, imageExtRegex as li, cloudfrontConfigSchema as ln, isOpenAILikeProvider as lo, toolApprovalPolicySchema as lr, FILE_FILTER_FIELDS as ls, CacheKeys as lt, getEffectivePermissions as m, ThinkingLevel as ma, isAnthropicTextDocumentType as mi, contextPruningSchema as mn, openAISettings as mo, vertexAISchema as mr, MAX_PII_CUSTOM_REGEX_INSTRUCTIONS as ms, EImageOutputType as mt, clearAllConversations as n, ImageVisionTool as na, excelFileTypes as ni, baseEndpointSchema as nn, imageDetailValue as no, stripServerNamePrefix as nr, getTagsForRating as ns, updateResourcePermissionsRequestSchema as nt, deleteAgentApiKey as o, ReasoningContext as oa, fullMimeTypesList as oi, buildServerNameAliases as on, isDocumentSupportedProvider as oo, supportsBalanceCheck as or, CONVERSATION_STARTER_FILTER_FIELDS as os, AuthKeys as ot, getCustomConfigSpeech as p, ThinkingDisplay as pa, isAnthropicDocumentType as pi, configSchema as pn, openAISchema as po, validateVisionModel as pr, MAX_PII_CUSTOM_REGEX_CHARACTERS as ps, DEFAULT_MEMORY_MAX_INPUT_TOKENS as pt, accessRoleSchema as q, getGoogleThinkingBudgetBounds as qa, generateGoogleSchema as qi, rateLimitSchema as qn, resolveAllowedStatefulCodeEnvironments as qo, codeInterpreterMimeTypes as qr, unattributedAssistantContentSchema as qs, allowedAddressesSchema as qt, createAgentApiKey as r, MYTHOS_CLASS_FAMILIES as ra, excelMimeTypes as ri, bedrockEndpointSchema as rn, inputTokensIncludesCache as ro, stripServerNamePrefixes as rr, toMinimalFeedback as rs, updateResourcePermissionsResponseSchema as rt, deletePreset as s, ReasoningEffort as sa, getConfiguredMimeAccept as si, checkpointerSchema as sn, isImageVisionTool as so, toolApprovalHookConfigSchema as sr, CONVERSATION_TITLE_FILTER_FIELDS as ss, BASE_ONLY_CONFIG_SECTIONS as st, cancelMCPOAuth as t, ImageDetail as ta, endpointFileConfigSchema as ti, balanceSchema as tn, imageDetailNumeric as to, splitToolCallName as tr, getTagByKey as ts, resourcePermissionsResponseSchema as tt, getAllEffectivePermissions as u, ReasoningResponseKey as ua, imageMimeTypes as ui, codeEnvironmentPermissionDecisionSchema as un, isParamEndpoint as uo, transactionsSchema as ur, FILTER_PII_STARTER_PATTERNS as us, Capabilities as ut, getSharedLink as v, agentsSettings as va, megabyte as vi, defaultModels as vn, resolveAgentSkillsScope as vo, MCPOptionsSchema as vr, MAX_PII_PATTERN_LENGTH as vs, ForkOptions as vt, revokeAllUserKeys as w, cacheSubsetProviders as wa, supportedMimeTypes as wi, fileStorageSchema as wn, tExampleSchema as wo, SSEOptionsSchema as wr, STORED_MESSAGE_FILTER_FIELDS as ws, MAX_SUBAGENT_GRAPH_NODES as wt, reinitializeMCPServer as x, anthropicSettings as xa, retrievalMimeTypes as xi, endpointSchema as xn, tConversationSchema as xo, MCP_SERVER_TITLE_ERROR as xr, MODEL_PARAMETER_FILTER_FIELDS as xs, KnownEndpoints as xt, getSharedMessages as y, anthropicBaseSchema as ya, mergeFileConfig as yi, defaultRetrievalModels as yn, subagentThreadLineageSchema as yo, MCPServerUserInputSchema as yr, MEMORY_FILTER_FIELDS as ys, ImageDetailCost as yt, DynamicQueryKeys as z, eReasoningParameterFormatSchema as za, MAX_SUBAGENTS_CEILING as zi, modelConfigSchema as zn, Tools as zo, loginPage as zr, hasActivePiiFields as zs, SettingsTabValues as zt };
6680
8742
 
6681
- //# sourceMappingURL=data-service-BsdHkdKS.mjs.map
8743
+ //# sourceMappingURL=data-service-CaB7saTP.mjs.map