mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-27 04:07:05 +00:00
🧩 fix: Normalize MCP UI Resource Rendering (#14868)
* fix: normalize MCP UI resource rendering * fix: filter unsupported MCP UI resources * fix: preserve MCP UI marker examples * fix: handle MCP UI resource edge cases * fix: harden MCP UI marker sanitization * fix: scope MCP UI marker sanitization * fix: parse MCP UI marker contexts * fix: align MCP UI sanitizer parsing * fix: match MCP UI renderer syntax * fix: align blockquote marker spans * fix: decode MCP UI text node sources * fix: sanitize nested subagent markers * fix: bound MCP UI sanitizer traversal * fix: keep MCP UI marker mapping linear * style: sort security patch imports * fix: harden nested MCP UI sanitization * fix: mirror citation cleanup for MCP UI markers * fix: clean decoded citation markers * fix: clean assembled citation markers * fix: align MCP marker sanitization with rendering * fix: match persisted MCP marker render paths * fix: preserve highlighted citation boundaries * fix: align MCP markers across content renderers * fix: preserve citation renderer boundaries * fix: match legacy thinking trim semantics
This commit is contained in:
parent
eb3b353712
commit
1d789c41a5
20 changed files with 1758 additions and 272 deletions
|
|
@ -1,11 +1,78 @@
|
|||
const { v4: uuidv4 } = require('uuid');
|
||||
const { logger, getTenantId } = require('@librechat/data-schemas');
|
||||
const { EModelEndpoint, Constants, openAISettings } = require('librechat-data-provider');
|
||||
const mongoose = require('mongoose');
|
||||
const {
|
||||
logger,
|
||||
getTenantId,
|
||||
sanitizeUIResourceContent,
|
||||
stripMessageUIResourceMarkers,
|
||||
} = require('@librechat/data-schemas');
|
||||
const { EModelEndpoint, Constants, Tools, openAISettings } = require('librechat-data-provider');
|
||||
const { getEndpointsConfig } = require('~/server/services/Config');
|
||||
const { createImportBatchBuilder } = require('./importBatchBuilder');
|
||||
const { resolveImportDefaultModel } = require('./defaults');
|
||||
const { cloneMessagesWithTimestamps } = require('./fork');
|
||||
|
||||
const castImportedBoolean = mongoose.Schema.Types.Boolean.cast();
|
||||
const castImportedString = mongoose.Schema.Types.String.cast();
|
||||
|
||||
function isImportedAssistantMessage(isCreatedByUser) {
|
||||
if (isCreatedByUser === null) {
|
||||
return false;
|
||||
}
|
||||
if (isCreatedByUser === undefined) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return castImportedBoolean(isCreatedByUser) !== true;
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function isImportedAssistantContent(isCreatedByUser) {
|
||||
try {
|
||||
return castImportedBoolean(isCreatedByUser) !== true;
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function castPersistedImportedText(text) {
|
||||
try {
|
||||
return castImportedString(text);
|
||||
} catch {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeImportedArray(value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return Array.isArray(value) ? value : [value];
|
||||
}
|
||||
|
||||
/** Removes executable legacy MCP-UI payloads from untrusted conversation imports. */
|
||||
function sanitizeImportedMessage(message) {
|
||||
const sanitizeTextMarkers = isImportedAssistantMessage(message.isCreatedByUser);
|
||||
const sanitizeContentMarkers = isImportedAssistantContent(message.isCreatedByUser);
|
||||
const text = castPersistedImportedText(message.text);
|
||||
const content = normalizeImportedArray(message.content);
|
||||
const attachments = normalizeImportedArray(message.attachments);
|
||||
return {
|
||||
...message,
|
||||
...(text !== message.text && { text }),
|
||||
...(sanitizeTextMarkers &&
|
||||
typeof text === 'string' && { text: stripMessageUIResourceMarkers(text, false) }),
|
||||
...(content && {
|
||||
content: sanitizeUIResourceContent(content, sanitizeContentMarkers),
|
||||
}),
|
||||
...(attachments && {
|
||||
attachments: attachments.filter((attachment) => attachment?.type !== Tools.ui_resources),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate importer function based on the provided JSON data.
|
||||
*
|
||||
|
|
@ -283,10 +350,13 @@ async function importLibreChatConvo(
|
|||
return flatMessages;
|
||||
};
|
||||
|
||||
const flatMessages = flattenMessages(messagesToImport);
|
||||
const flatMessages = flattenMessages(messagesToImport).map(sanitizeImportedMessage);
|
||||
cloneMessagesWithTimestamps(flatMessages, importBatchBuilder);
|
||||
} else if (messagesToImport) {
|
||||
cloneMessagesWithTimestamps(messagesToImport, importBatchBuilder);
|
||||
cloneMessagesWithTimestamps(
|
||||
messagesToImport.map(sanitizeImportedMessage),
|
||||
importBatchBuilder,
|
||||
);
|
||||
for (const message of messagesToImport) {
|
||||
if (!firstMessageDate && message.createdAt) {
|
||||
firstMessageDate = new Date(message.createdAt);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ const path = require('path');
|
|||
const {
|
||||
EModelEndpoint,
|
||||
Constants,
|
||||
ContentTypes,
|
||||
Tools,
|
||||
RetentionMode,
|
||||
openAISettings,
|
||||
anthropicSettings,
|
||||
|
|
@ -877,6 +879,158 @@ describe('importLibreChatConvo', () => {
|
|||
expect(importBatchBuilder.saveBatch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it.each([
|
||||
['linear', false, false],
|
||||
['recursive', true, false],
|
||||
['numeric-author', false, 0],
|
||||
['omitted-author', false, undefined],
|
||||
])('strips MCP-UI attachments from %s imports', async (_format, recursive, authorFlag) => {
|
||||
const message = {
|
||||
messageId: 'message-1',
|
||||
parentMessageId: Constants.NO_PARENT,
|
||||
text: { _id: '\\ui{malicious}' },
|
||||
isCreatedByUser: authorFlag,
|
||||
content: [
|
||||
{ type: ContentTypes.TEXT, text: 'Before \\ui{malicious} after' },
|
||||
{ type: ContentTypes.TEXT, text: '`\\ui{literal}`' },
|
||||
{
|
||||
type: ContentTypes.TEXT,
|
||||
text: {
|
||||
value: 'Object \\ui{malicious} value',
|
||||
annotations: [{ type: 'citation' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
subagent_content: [{ type: ContentTypes.TEXT, text: 'Nested \\ui{malicious} content' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
attachments: [
|
||||
{
|
||||
type: Tools.ui_resources,
|
||||
[Tools.ui_resources]: [
|
||||
{
|
||||
resourceId: 'malicious',
|
||||
mimeType: 'application/vnd.mcp-ui.remote-dom+javascript',
|
||||
text: "root.innerHTML='<img src=x onerror=alert(window.origin)>'",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ type: Tools.web_search, [Tools.web_search]: { results: [] } },
|
||||
],
|
||||
};
|
||||
const jsonData = {
|
||||
conversationId: 'malicious-import',
|
||||
title: 'Malicious import',
|
||||
recursive,
|
||||
...(recursive ? { messagesTree: [message] } : { messages: [message] }),
|
||||
};
|
||||
const importBatchBuilder = new ImportBatchBuilder('user-123');
|
||||
|
||||
const importer = getImporter(jsonData);
|
||||
await importer(jsonData, 'user-123', () => importBatchBuilder);
|
||||
|
||||
expect(importBatchBuilder.messages[0].attachments).toEqual([
|
||||
{ type: Tools.web_search, [Tools.web_search]: { results: [] } },
|
||||
]);
|
||||
expect(importBatchBuilder.messages[0].text).toBe('');
|
||||
expect(importBatchBuilder.messages[0].content).toEqual([
|
||||
{ type: ContentTypes.TEXT, text: 'Before after' },
|
||||
{ type: ContentTypes.TEXT, text: '`\\ui{literal}`' },
|
||||
{
|
||||
type: ContentTypes.TEXT,
|
||||
text: { value: 'Object value', annotations: [{ type: 'citation' }] },
|
||||
},
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
subagent_content: [{ type: ContentTypes.TEXT, text: 'Nested content' }],
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('sanitizes singleton content and attachment fields before Mongoose array casting', async () => {
|
||||
const message = {
|
||||
messageId: 'message-1',
|
||||
parentMessageId: Constants.NO_PARENT,
|
||||
text: '\\ui{malicious}',
|
||||
isCreatedByUser: false,
|
||||
error: true,
|
||||
content: { type: ContentTypes.TEXT, text: 'Before \\ui{malicious} after' },
|
||||
attachments: { type: Tools.ui_resources, [Tools.ui_resources]: [] },
|
||||
};
|
||||
const jsonData = {
|
||||
conversationId: 'singleton-import',
|
||||
title: 'Singleton fields',
|
||||
recursive: false,
|
||||
messages: [message],
|
||||
};
|
||||
const importBatchBuilder = new ImportBatchBuilder('user-123');
|
||||
|
||||
const importer = getImporter(jsonData);
|
||||
await importer(jsonData, 'user-123', () => importBatchBuilder);
|
||||
|
||||
expect(importBatchBuilder.messages[0].content).toEqual([
|
||||
{ type: ContentTypes.TEXT, text: 'Before after' },
|
||||
]);
|
||||
expect(importBatchBuilder.messages[0].attachments).toEqual([]);
|
||||
expect(importBatchBuilder.messages[0].text).toBe('');
|
||||
});
|
||||
|
||||
it.each([true, null])(
|
||||
'matches text and content renderers for author flag %s while stripping attachments',
|
||||
async (authorFlag) => {
|
||||
const message = {
|
||||
messageId: 'message-1',
|
||||
parentMessageId: Constants.NO_PARENT,
|
||||
text: 'Example: \\ui{literal}',
|
||||
isCreatedByUser: authorFlag,
|
||||
content: [
|
||||
{ type: ContentTypes.TEXT, text: 'Part: \\ui{literal}' },
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
name: Constants.SUBAGENT,
|
||||
output: 'Legacy \\ui{nested} output',
|
||||
subagent_content: [{ type: ContentTypes.TEXT, text: 'Nested \\ui{nested} text' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
attachments: [{ type: Tools.ui_resources, [Tools.ui_resources]: [] }],
|
||||
};
|
||||
const jsonData = {
|
||||
conversationId: 'user-marker-import',
|
||||
title: 'User marker import',
|
||||
recursive: false,
|
||||
messages: [message],
|
||||
};
|
||||
const importBatchBuilder = new ImportBatchBuilder('user-123');
|
||||
|
||||
const importer = getImporter(jsonData);
|
||||
await importer(jsonData, 'user-123', () => importBatchBuilder);
|
||||
|
||||
expect(importBatchBuilder.messages[0].text).toBe('Example: \\ui{literal}');
|
||||
expect(importBatchBuilder.messages[0].content).toEqual([
|
||||
{
|
||||
type: ContentTypes.TEXT,
|
||||
text: authorFlag === true ? 'Part: \\ui{literal}' : 'Part: ',
|
||||
},
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
name: Constants.SUBAGENT,
|
||||
output: 'Legacy output',
|
||||
subagent_content: [{ type: ContentTypes.TEXT, text: 'Nested text' }],
|
||||
},
|
||||
},
|
||||
]);
|
||||
expect(importBatchBuilder.messages[0].attachments).toEqual([]);
|
||||
},
|
||||
);
|
||||
|
||||
it('should import linear, non-recursive thread correctly with correct endpoint', async () => {
|
||||
mockGetEndpointsConfig.mockResolvedValue({
|
||||
[EModelEndpoint.azureOpenAI]: {},
|
||||
|
|
|
|||
322
bun.lock
322
bun.lock
|
|
@ -5,12 +5,14 @@
|
|||
"": {
|
||||
"name": "LibreChat",
|
||||
"devDependencies": {
|
||||
"@antithesishq/bombadil": "0.6.1",
|
||||
"@axe-core/playwright": "^4.10.1",
|
||||
"@eslint/compat": "^1.2.6",
|
||||
"@eslint/eslintrc": "^3.3.4",
|
||||
"@eslint/js": "^9.20.0",
|
||||
"@playwright/test": "^1.56.1",
|
||||
"@types/react-virtualized": "^9.22.0",
|
||||
"brace-expansion": "^2.1.2",
|
||||
"caniuse-lite": "^1.0.30001741",
|
||||
"cross-env": "^7.0.3",
|
||||
"elliptic": "^6.6.1",
|
||||
|
|
@ -51,11 +53,11 @@
|
|||
"@azure/storage-blob": "^12.30.0",
|
||||
"@google/genai": "^2.8.0",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@librechat/agents": "^3.3.11",
|
||||
"@librechat/agents": "^3.5.1",
|
||||
"@librechat/api": "*",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||
"@modelcontextprotocol/sdk": "^1.30.0",
|
||||
"@node-saml/passport-saml": "^5.1.0",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/instrumentation-express": "^0.56.0",
|
||||
|
|
@ -109,7 +111,7 @@
|
|||
"mongodb": "^6.14.2",
|
||||
"mongoose": "^8.24.1",
|
||||
"multer": "^2.2.0",
|
||||
"nanoid": "^3.3.7",
|
||||
"nanoid": "^3.3.18",
|
||||
"node-fetch": "^2.7.0",
|
||||
"nodemailer": "^9.0.1",
|
||||
"ollama": "^0.5.0",
|
||||
|
|
@ -127,10 +129,11 @@
|
|||
"pdfjs-dist": "^5.4.624",
|
||||
"prom-client": "^15.1.3",
|
||||
"rate-limit-redis": "^4.2.0",
|
||||
"sanitize-html": "^2.13.0",
|
||||
"re2js": "^2.8.6",
|
||||
"sanitize-html": "^2.17.6",
|
||||
"sharp": "^0.35.3",
|
||||
"ua-parser-js": "^1.0.36",
|
||||
"undici": "^7.24.1",
|
||||
"undici": "^7.29.0",
|
||||
"winston": "^3.11.0",
|
||||
"winston-daily-rotate-file": "^5.0.0",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
|
||||
|
|
@ -139,7 +142,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.29.5",
|
||||
"@types/sanitize-html": "^2.13.0",
|
||||
"@types/sanitize-html": "^2.16.1",
|
||||
"jest": "^30.2.0",
|
||||
"mongodb-memory-server": "^11.0.1",
|
||||
"nodemon": "^3.1.14",
|
||||
|
|
@ -207,7 +210,7 @@
|
|||
"mdast-util-from-markdown": "^2.0.1",
|
||||
"mdast-util-gfm": "^3.0.0",
|
||||
"mdast-util-math": "^3.0.0",
|
||||
"mermaid": "^11.15.0",
|
||||
"mermaid": "^11.16.1",
|
||||
"micromark-extension-directive": "^3.0.1",
|
||||
"micromark-extension-gfm": "^3.0.0",
|
||||
"micromark-extension-llm-math": "^3.1.0",
|
||||
|
|
@ -296,6 +299,8 @@
|
|||
"dependencies": {
|
||||
"@langchain/langgraph-checkpoint": "^1.1.2",
|
||||
"@langchain/langgraph-checkpoint-mongodb": "^1.4.0",
|
||||
"cluster-key-slot": "^1.1.2",
|
||||
"proxy-from-env": "^2.1.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.29.5",
|
||||
|
|
@ -311,7 +316,7 @@
|
|||
"@types/node": "^24.12.4",
|
||||
"@types/node-fetch": "^2.6.13",
|
||||
"@types/react": "^18.2.18",
|
||||
"@types/sanitize-html": "^2.13.0",
|
||||
"@types/sanitize-html": "^2.16.1",
|
||||
"@types/supertest": "^7.2.0",
|
||||
"@types/yauzl": "^2.10.3",
|
||||
"aws-sdk-client-mock": "^4.1.0",
|
||||
|
|
@ -325,10 +330,9 @@
|
|||
"lodash": "^4.17.23",
|
||||
"mammoth": "^1.11.0",
|
||||
"mongodb": "^6.14.2",
|
||||
"nanoid": "^3.3.7",
|
||||
"nanoid": "^3.3.18",
|
||||
"pdfjs-dist": "^5.4.624",
|
||||
"rimraf": "^6.1.3",
|
||||
"sanitize-html": "^2.13.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsdown": "^0.22.2",
|
||||
"typescript": "^5.9.3",
|
||||
|
|
@ -349,9 +353,9 @@
|
|||
"@azure/storage-blob": "^12.30.0",
|
||||
"@google/genai": "^2.8.0",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@librechat/agents": "^3.3.11",
|
||||
"@librechat/agents": "^3.5.1",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||
"@modelcontextprotocol/sdk": "^1.30.0",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/instrumentation-express": "^0.56.0",
|
||||
"@opentelemetry/instrumentation-http": "^0.207.0",
|
||||
|
|
@ -394,9 +398,10 @@
|
|||
"pdfjs-dist": "^5.4.624",
|
||||
"prom-client": "^15.1.3",
|
||||
"rate-limit-redis": "^4.2.0",
|
||||
"sanitize-html": "^2.13.0",
|
||||
"re2js": "^2.8.6",
|
||||
"sanitize-html": "^2.17.6",
|
||||
"sharp": "^0.35.3",
|
||||
"undici": "^7.24.1",
|
||||
"undici": "^7.29.0",
|
||||
"yauzl": "^3.2.1",
|
||||
"zod": "^3.22.4",
|
||||
},
|
||||
|
|
@ -490,7 +495,7 @@
|
|||
"dependencies": {
|
||||
"axios": "^1.16.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"js-yaml": "^4.2.0",
|
||||
"js-yaml": "^4.3.1",
|
||||
"zod": "^3.22.4",
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -522,6 +527,16 @@
|
|||
"packages/data-schemas": {
|
||||
"name": "@librechat/data-schemas",
|
||||
"version": "0.0.68",
|
||||
"dependencies": {
|
||||
"mdast-util-directive": "^3.0.0",
|
||||
"mdast-util-from-markdown": "^2.0.1",
|
||||
"mdast-util-gfm": "^3.0.0",
|
||||
"mdast-util-math": "^3.0.0",
|
||||
"micromark-extension-directive": "^3.0.1",
|
||||
"micromark-extension-gfm": "^3.0.0",
|
||||
"micromark-extension-llm-math": "^3.1.0",
|
||||
"micromark-util-decode-string": "^2.0.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/jest": "^29.5.2",
|
||||
|
|
@ -541,7 +556,7 @@
|
|||
"lodash": "^4.17.23",
|
||||
"meilisearch": "^0.38.0",
|
||||
"mongoose": "^8.24.1",
|
||||
"nanoid": "^3.3.7",
|
||||
"nanoid": "^3.3.18",
|
||||
"winston": "^3.17.0",
|
||||
"winston-daily-rotate-file": "^5.0.0",
|
||||
},
|
||||
|
|
@ -552,7 +567,6 @@
|
|||
"@opentelemetry/core": "^2.9.0",
|
||||
"@opentelemetry/propagator-jaeger": "^2.10.0",
|
||||
"@xmldom/xmldom": "^0.8.13",
|
||||
"brace-expansion": "^5.0.8",
|
||||
"elliptic": "^6.6.1",
|
||||
"fast-xml-parser": "5.7.2",
|
||||
"form-data": "^4.0.6",
|
||||
|
|
@ -582,6 +596,8 @@
|
|||
|
||||
"@anthropic-ai/vertex-sdk": ["@anthropic-ai/vertex-sdk@0.16.1", "", { "dependencies": { "@anthropic-ai/sdk": ">=0.50.3 <1", "google-auth-library": "^9.4.2" } }, "sha512-NQSJTmHFqJP32W4I+UyZ42ioUkd8avdye259Cs+P9yhi+XdI4wk7sDVnmVNNTiMtN08WXyELnAQPG2gcLQFXdQ=="],
|
||||
|
||||
"@antithesishq/bombadil": ["@antithesishq/bombadil@0.6.1", "", { "bin": { "bombadil": "bin/bombadil.js" } }, "sha512-d1iufG3MI7gSMSiSmMeNdcMW+qR0yQXL2zdkVynC3n3DYgFJYlYXKUQzygmqU12m4RWlR5iOdQU1hsx5UT6+IA=="],
|
||||
|
||||
"@apideck/better-ajv-errors": ["@apideck/better-ajv-errors@0.3.6", "", { "dependencies": { "json-schema": "^0.4.0", "jsonpointer": "^5.0.0", "leven": "^3.1.0" }, "peerDependencies": { "ajv": ">=8" } }, "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA=="],
|
||||
|
||||
"@ariakit/components": ["@ariakit/components@0.1.2", "", { "dependencies": { "@ariakit/store": "0.1.2", "@ariakit/utils": "0.1.2" } }, "sha512-tvh2P0x1cJnoPXnmDEJwdRk3z7x6cTB8ArctcZdAUXlRg9tuwW/rJoBFJMzD5qMI9CDDlQ3Zctx58HvENw4BYw=="],
|
||||
|
|
@ -1518,7 +1534,7 @@
|
|||
|
||||
"@lezer/lr": ["@lezer/lr@1.4.2", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA=="],
|
||||
|
||||
"@librechat/agents": ["@librechat/agents@3.3.11", "", { "dependencies": { "@anthropic-ai/sdk": "^0.115.0", "@aws-sdk/client-bedrock-runtime": "^3.1075.0", "@langchain/anthropic": "1.5.2", "@langchain/aws": "^1.4.2", "@langchain/core": "^1.2.3", "@langchain/deepseek": "^1.1.3", "@langchain/google-common": "2.2.0", "@langchain/google-gauth": "2.2.0", "@langchain/google-genai": "2.2.0", "@langchain/google-vertexai": "2.2.0", "@langchain/langgraph": "1.4.8", "@langchain/mistralai": "^1.2.0", "@langchain/openai": "1.5.5", "@langchain/textsplitters": "^1.0.1", "@langchain/xai": "^1.4.3", "@langfuse/core": "^5.4.1", "@langfuse/langchain": "^5.4.1", "@langfuse/otel": "^5.4.1", "@langfuse/tracing": "^5.4.1", "@opentelemetry/context-async-hooks": "^2.9.0", "@opentelemetry/sdk-node": "^0.220.0", "@types/diff": "^7.0.2", "ai-tokenizer": "^1.0.6", "axios": "^1.18.1", "cheerio": "^1.0.0", "diff": "^9.0.0", "dotenv": "^16.4.7", "https-proxy-agent": "^7.0.6", "mathjs": "^15.2.0", "nanoid": "^3.3.7", "okapibm25": "^1.4.1", "openai": "^6.46.0", "reo-census": "^1.2.9", "uuid": "^11.1.1" }, "peerDependencies": { "@anthropic-ai/sandbox-runtime": "^0.0.67" }, "optionalPeers": ["@anthropic-ai/sandbox-runtime"] }, "sha512-rCCUQbi6b2HcUfq11a/1FXR9JveCmV/30HH64TkVyVHoUkL7QlSd99rddaYRjnAcsGlWb1zY+0oHEO1jQ3m93A=="],
|
||||
"@librechat/agents": ["@librechat/agents@3.5.1", "", { "dependencies": { "@anthropic-ai/sdk": "^0.115.0", "@aws-sdk/client-bedrock-runtime": "^3.1075.0", "@langchain/anthropic": "1.5.2", "@langchain/aws": "^1.4.2", "@langchain/core": "^1.2.3", "@langchain/deepseek": "^1.1.3", "@langchain/google-common": "2.2.0", "@langchain/google-gauth": "2.2.0", "@langchain/google-genai": "2.2.0", "@langchain/google-vertexai": "2.2.0", "@langchain/langgraph": "1.4.8", "@langchain/mistralai": "^1.2.0", "@langchain/openai": "1.5.5", "@langchain/textsplitters": "^1.0.1", "@langchain/xai": "^1.4.3", "@langfuse/core": "^5.4.1", "@langfuse/langchain": "^5.4.1", "@langfuse/otel": "^5.4.1", "@langfuse/tracing": "^5.4.1", "@opentelemetry/context-async-hooks": "^2.9.0", "@opentelemetry/sdk-node": "^0.220.0", "@types/diff": "^7.0.2", "ai-tokenizer": "^1.0.6", "axios": "^1.18.1", "cheerio": "^1.0.0", "diff": "^9.0.0", "dotenv": "^16.4.7", "https-proxy-agent": "^7.0.6", "mathjs": "^15.2.0", "nanoid": "^3.3.18", "okapibm25": "^1.4.1", "openai": "^6.46.0", "reova": "^0.4.1", "socks-proxy-agent": "^8.0.5", "uuid": "^11.1.1" }, "peerDependencies": { "@anthropic-ai/sandbox-runtime": "^0.0.67" }, "optionalPeers": ["@anthropic-ai/sandbox-runtime"] }, "sha512-8y4gfZg8OD5BuykF8xixh71yafgmmk7dUFX8KN9O40/WkqfJTtA/FG7E48Ke+ben3xOoXE6aIc7fwmotrYrhKw=="],
|
||||
|
||||
"@librechat/api": ["@librechat/api@workspace:packages/api"],
|
||||
|
||||
|
|
@ -1546,7 +1562,7 @@
|
|||
|
||||
"@monaco-editor/react": ["@monaco-editor/react@4.7.0", "", { "dependencies": { "@monaco-editor/loader": "^1.5.0" }, "peerDependencies": { "monaco-editor": ">= 0.25.0 < 1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA=="],
|
||||
|
||||
"@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.3.1", "", { "dependencies": { "sparse-bitfield": "^3.0.3" } }, "sha512-6nZrq5kfAz0POWyhljnbWQQJQ5uT8oE2ddX303q1uY0tWsivWKgBDXBBvuFPwOqRRalXJuVO9EjOdVtuhLX0zg=="],
|
||||
"@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.4.13", "", { "dependencies": { "sparse-bitfield": "^3.0.3" } }, "sha512-E3Sv4eCYAlKYUTx8S3ioQcDUscOif+8zZ5OnW1IzJ+Tt+EO+ke8mn+Y3FX6N1H79picwbdOavVOb1jPi2EOyrg=="],
|
||||
|
||||
"@napi-rs/canvas": ["@napi-rs/canvas@0.1.96", "", { "optionalDependencies": { "@napi-rs/canvas-android-arm64": "0.1.96", "@napi-rs/canvas-darwin-arm64": "0.1.96", "@napi-rs/canvas-darwin-x64": "0.1.96", "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.96", "@napi-rs/canvas-linux-arm64-gnu": "0.1.96", "@napi-rs/canvas-linux-arm64-musl": "0.1.96", "@napi-rs/canvas-linux-riscv64-gnu": "0.1.96", "@napi-rs/canvas-linux-x64-gnu": "0.1.96", "@napi-rs/canvas-linux-x64-musl": "0.1.96", "@napi-rs/canvas-win32-arm64-msvc": "0.1.96", "@napi-rs/canvas-win32-x64-msvc": "0.1.96" } }, "sha512-6NNmNxvoJKeucVjxaaRUt3La2i5jShgiAbaY3G/72s1Vp3U06XPrAIxkAjBxpDcamEn/t+WJ4OOlGmvILo4/Ew=="],
|
||||
|
||||
|
|
@ -1970,7 +1986,7 @@
|
|||
|
||||
"@sinonjs/samsam": ["@sinonjs/samsam@8.0.3", "", { "dependencies": { "@sinonjs/commons": "^3.0.1", "type-detect": "^4.1.0" } }, "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ=="],
|
||||
|
||||
"@smithy/abort-controller": ["@smithy/abort-controller@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q=="],
|
||||
"@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
|
||||
|
||||
"@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw=="],
|
||||
|
||||
|
|
@ -1982,7 +1998,7 @@
|
|||
|
||||
"@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.4.16", "", { "dependencies": { "@smithy/core": "^3.31.1", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-QfuLWAkLzptffFW980AFeHZFdqds2B64rpEd3uJ6lgs3xVn9QegGMUgUcj+4d7dRrAsya3r58ZKpku97WcFb4w=="],
|
||||
|
||||
"@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.12", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA=="],
|
||||
"@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.11", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w=="],
|
||||
|
||||
"@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.11", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-3rEpo3G6f/nRS7fQDsZmxw/ius6rnlIpz4UX6FlALEzz8JoSxFmdBt0SZnthis+km7sQo6q5/3e+UJcuQivoXA=="],
|
||||
|
||||
|
|
@ -2024,7 +2040,7 @@
|
|||
|
||||
"@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
|
||||
|
||||
"@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg=="],
|
||||
"@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
|
||||
|
||||
"@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="],
|
||||
|
||||
|
|
@ -2588,7 +2604,7 @@
|
|||
|
||||
"bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="],
|
||||
|
||||
"balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
|
||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"bare-events": ["bare-events@2.6.0", "", {}, "sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg=="],
|
||||
|
||||
|
|
@ -2626,7 +2642,7 @@
|
|||
|
||||
"bowser": ["bowser@2.11.0", "", {}, "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="],
|
||||
|
||||
"brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="],
|
||||
"brace-expansion": ["brace-expansion@2.1.4", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg=="],
|
||||
|
||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||
|
||||
|
|
@ -2654,8 +2670,6 @@
|
|||
|
||||
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
|
||||
|
||||
"buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
|
||||
|
||||
"buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
|
||||
|
||||
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
|
||||
|
|
@ -2768,6 +2782,8 @@
|
|||
|
||||
"compression": ["compression@1.8.1", "", { "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", "negotiator": "~0.6.4", "on-headers": "~1.1.0", "safe-buffer": "5.2.1", "vary": "~1.1.2" } }, "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w=="],
|
||||
|
||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||
|
||||
"concat-stream": ["concat-stream@2.0.0", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A=="],
|
||||
|
||||
"confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
|
||||
|
|
@ -2934,7 +2950,7 @@
|
|||
|
||||
"date-fns": ["date-fns@3.3.1", "", {}, "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw=="],
|
||||
|
||||
"dayjs": ["dayjs@1.11.19", "", {}, "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="],
|
||||
"dayjs": ["dayjs@1.11.21", "", {}, "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
|
|
@ -3792,7 +3808,7 @@
|
|||
|
||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||
|
||||
"lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="],
|
||||
"lodash": ["lodash@4.18.1", "", {}, "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="],
|
||||
|
||||
"lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="],
|
||||
|
||||
|
|
@ -3916,7 +3932,7 @@
|
|||
|
||||
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
||||
|
||||
"mermaid": ["mermaid@11.16.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.2", "@iconify/utils": "^3.0.2", "@mermaid-js/parser": "^1.2.0", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", "cytoscape": "^3.33.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", "dayjs": "^1.11.20", "dompurify": "^3.3.3", "es-toolkit": "^1.45.1", "katex": "^0.16.45", "khroma": "^2.1.0", "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0 || ^12 || ^13 || ^14.0.0" } }, "sha512-Zvm3kbstgdpvIJPPItlL7fppIZ3kibvc1oZIGxdvk9t6UFz6flv+Jw7FtRGKwfcI8OckmH04LqG6LlS6X4B1pA=="],
|
||||
"mermaid": ["mermaid@11.16.1", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.2", "@iconify/utils": "^3.0.2", "@mermaid-js/parser": "^1.2.0", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", "cytoscape": "^3.33.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", "dayjs": "^1.11.20", "dompurify": "^3.3.3", "es-toolkit": "^1.45.1", "katex": "^0.16.45", "khroma": "^2.1.0", "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0 || ^12 || ^13 || ^14.0.0" } }, "sha512-TQsq6u22fAn3rek5VOubrhKPo1g5hwC3FXUN9hiyupTckcYiGuuKGkNQrKYwGJkXUxZdojwRG46gsSCFZMDp4g=="],
|
||||
|
||||
"methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="],
|
||||
|
||||
|
|
@ -4022,7 +4038,7 @@
|
|||
|
||||
"monaco-editor": ["monaco-editor@0.56.0", "", { "dependencies": { "dompurify": "3.4.8", "marked": "14.0.0" } }, "sha512-sXboRm3BeBeLm938eaiyLMe0OxzfXIlZvbv4ir/jVgQy1zDhWjgmny0WoN45fuDKhCCQsYMbBJrv/A6jd8aCUg=="],
|
||||
|
||||
"mongodb": ["mongodb@6.14.2", "", { "dependencies": { "@mongodb-js/saslprep": "^1.1.9", "bson": "^6.10.3", "mongodb-connection-string-url": "^3.0.0" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", "snappy": "^7.2.2", "socks": "^2.7.1" }, "optionalPeers": ["@mongodb-js/zstd", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-kMEHNo0F3P6QKDq17zcDuPeaywK/YaJVCEQRzPF3TOM/Bl9MFg64YE5Tu7ifj37qZJMhwU1tl2Ioivws5gRG5Q=="],
|
||||
"mongodb": ["mongodb@6.21.0", "", { "dependencies": { "@mongodb-js/saslprep": "^1.3.0", "bson": "^6.10.4", "mongodb-connection-string-url": "^3.0.2" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", "snappy": "^7.3.2", "socks": "^2.7.1" }, "optionalPeers": ["@aws-sdk/credential-providers", "@mongodb-js/zstd", "gcp-metadata", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-URyb/VXMjJ4da46OeSXg+puO39XH9DeQpWCslifrRn9JWugy0D+DvvBvkm2WxmHe61O/H19JM66p1z7RHVkZ6A=="],
|
||||
|
||||
"mongodb-connection-string-url": ["mongodb-connection-string-url@3.0.2", "", { "dependencies": { "@types/whatwg-url": "^11.0.2", "whatwg-url": "^14.1.0 || ^13.0.0" } }, "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA=="],
|
||||
|
||||
|
|
@ -4050,7 +4066,7 @@
|
|||
|
||||
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||
"nanoid": ["nanoid@3.3.18", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w=="],
|
||||
|
||||
"napi-postinstall": ["napi-postinstall@0.3.4", "", { "bin": "lib/cli.js" }, "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ=="],
|
||||
|
||||
|
|
@ -4396,6 +4412,8 @@
|
|||
|
||||
"rc-util": ["rc-util@5.38.1", "", { "dependencies": { "@babel/runtime": "^7.18.3", "react-is": "^18.2.0" }, "peerDependencies": { "react": ">=16.9.0", "react-dom": ">=16.9.0" } }, "sha512-e4ZMs7q9XqwTuhIK7zBIVFltUtMSjphuPPQXHoHlzRzNdOwUxDejo0Zls5HYaJfRKNURcsS/ceKVULlhjBrxng=="],
|
||||
|
||||
"re2js": ["re2js@2.8.6", "", {}, "sha512-xLgQil4kIUCrAzVk9fRSkxkFNwmygLFjVxXrLc65aE1F0+Zsb8rxumFBy4XKyvgMCTL6kilDq3EZ0piE2dP/Dg=="],
|
||||
|
||||
"react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="],
|
||||
|
||||
"react-avatar-editor": ["react-avatar-editor@13.0.2", "", { "dependencies": { "@babel/plugin-transform-runtime": "^7.12.1", "@babel/runtime": "^7.12.5", "prop-types": "^15.7.2" }, "peerDependencies": { "react": "^0.14.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom": "^0.14.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, "sha512-a4ajbi7lwDh98kgEtSEeKMu0vs0CHTczkq4Xcxr1EiwMFH1GlgHCEtwGU8q/H5W8SeLnH4KPK8LUjEEaZXklxQ=="],
|
||||
|
|
@ -4502,7 +4520,7 @@
|
|||
|
||||
"remove-accents": ["remove-accents@0.5.0", "", {}, "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A=="],
|
||||
|
||||
"reo-census": ["reo-census@1.2.9", "", {}, "sha512-QPnAyRk6gUK9h2XJy9yTXiA91+LEHahmzbRdfb6DigAoe1S/nKg2LXc+/m3//HGyMPAkCFVz/FJJ8YrKm5IrXw=="],
|
||||
"reova": ["reova@0.4.1", "", {}, "sha512-9TNaquUZIeT+2SYAy5on/ZTCTF+cWFJNeZ1ugV1K2HdepeswSzGRl+pBghuXqr0ur4tWfaxkvW5etPX0e7mQNg=="],
|
||||
|
||||
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
|
||||
|
||||
|
|
@ -4630,13 +4648,19 @@
|
|||
|
||||
"slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="],
|
||||
|
||||
"smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
|
||||
|
||||
"smob": ["smob@1.4.1", "", {}, "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ=="],
|
||||
|
||||
"socks": ["socks@2.8.9", "", { "dependencies": { "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" } }, "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw=="],
|
||||
|
||||
"socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="],
|
||||
|
||||
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"source-map-support": ["source-map-support@0.5.13", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w=="],
|
||||
"source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
|
||||
|
||||
"space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="],
|
||||
|
||||
|
|
@ -4884,7 +4908,7 @@
|
|||
|
||||
"underscore": ["underscore@1.13.8", "", {}, "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ=="],
|
||||
|
||||
"undici": ["undici@7.24.4", "", {}, "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w=="],
|
||||
"undici": ["undici@7.29.0", "", {}, "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw=="],
|
||||
|
||||
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
||||
|
||||
|
|
@ -5096,7 +5120,7 @@
|
|||
|
||||
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
|
||||
|
||||
"yauzl": ["yauzl@3.2.1", "", { "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" } }, "sha512-k1isifdbpNSFEHFJ1ZY4YDewv0IH9FR61lDetaRMD3j2ae3bIXGV+7c+LHCqtQGofSd8PIyV4X6+dHMAnSr60A=="],
|
||||
"yauzl": ["yauzl@3.4.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw=="],
|
||||
|
||||
"yn": ["yn@3.1.1", "", {}, "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="],
|
||||
|
||||
|
|
@ -5486,8 +5510,6 @@
|
|||
|
||||
"@hyperdx/otel-web/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.218.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.218.0", "import-in-the-middle": "^3.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-mIZil8Es+sYDK5m+DQiwAwF57F14TF2YlEqvIjZ/RQWcxDBwRGsKfdK2Tv65OU9meQKCMzSIFS9mxAcnAb6Bkg=="],
|
||||
|
||||
"@hyperdx/otel-web/lodash": ["lodash@4.18.1", "", {}, "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="],
|
||||
|
||||
"@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
|
||||
|
||||
"@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
||||
|
|
@ -5550,8 +5572,6 @@
|
|||
|
||||
"@langchain/google-gauth/google-auth-library": ["google-auth-library@10.9.1", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^7.1.4", "gcp-metadata": "8.1.2", "google-logging-utils": "1.1.3", "jws": "^4.0.0" } }, "sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw=="],
|
||||
|
||||
"@langchain/langgraph-checkpoint-mongodb/mongodb": ["mongodb@6.21.0", "", { "dependencies": { "@mongodb-js/saslprep": "^1.3.0", "bson": "^6.10.4", "mongodb-connection-string-url": "^3.0.2" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", "snappy": "^7.3.2", "socks": "^2.7.1" }, "optionalPeers": ["@aws-sdk/credential-providers", "@mongodb-js/zstd", "gcp-metadata", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-URyb/VXMjJ4da46OeSXg+puO39XH9DeQpWCslifrRn9JWugy0D+DvvBvkm2WxmHe61O/H19JM66p1z7RHVkZ6A=="],
|
||||
|
||||
"@langchain/langgraph-sdk/p-retry": ["p-retry@7.1.1", "", { "dependencies": { "is-network-error": "^1.1.0" } }, "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w=="],
|
||||
|
||||
"@langchain/openai/openai": ["openai@6.49.0", "", { "peerDependencies": { "@aws-sdk/credential-provider-node": ">=3.972.0 <4", "@smithy/hash-node": ">=4.3.0 <5", "@smithy/signature-v4": ">=5.4.0 <6", "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["@aws-sdk/credential-provider-node", "@smithy/hash-node", "@smithy/signature-v4", "ws", "zod"] }, "sha512-aYCc0C6L864eR6WSYIwQGyXriw/nIyZx0ObvhzOEVuk0zoBDpynjSbrionWI7q65B5H8jJX0DXR9snEzM6bfPg=="],
|
||||
|
|
@ -5564,18 +5584,10 @@
|
|||
|
||||
"@librechat/agents/diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="],
|
||||
|
||||
"@librechat/agents/nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="],
|
||||
|
||||
"@librechat/agents/openai": ["openai@6.49.0", "", { "peerDependencies": { "@aws-sdk/credential-provider-node": ">=3.972.0 <4", "@smithy/hash-node": ">=4.3.0 <5", "@smithy/signature-v4": ">=5.4.0 <6", "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["@aws-sdk/credential-provider-node", "@smithy/hash-node", "@smithy/signature-v4", "ws", "zod"] }, "sha512-aYCc0C6L864eR6WSYIwQGyXriw/nIyZx0ObvhzOEVuk0zoBDpynjSbrionWI7q65B5H8jJX0DXR9snEzM6bfPg=="],
|
||||
|
||||
"@librechat/agents/uuid": ["uuid@11.1.1", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime": ["@aws-sdk/client-bedrock-runtime@3.1013.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.22", "@aws-sdk/credential-provider-node": "^3.972.23", "@aws-sdk/eventstream-handler-node": "^3.972.11", "@aws-sdk/middleware-eventstream": "^3.972.8", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/middleware-websocket": "^3.972.13", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/token-providers": "3.1013.0", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.9", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.12", "@smithy/eventstream-serde-browser": "^4.2.12", "@smithy/eventstream-serde-config-resolver": "^4.3.12", "@smithy/eventstream-serde-node": "^4.2.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.26", "@smithy/middleware-retry": "^4.4.43", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.42", "@smithy/util-defaults-mode-node": "^4.2.45", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-LU80q1avpBwQ0eVAGbQpPApdVY4vcdBEIycY5iaznI10mdabeG83nrFySJrZ8knX7G6hl5d5KIOSjcpnolMKSA=="],
|
||||
|
||||
"@librechat/backend/@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
|
||||
|
||||
"@librechat/backend/@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.0", "", { "dependencies": { "@smithy/abort-controller": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Rnq9vQWiR1+/I6NZZMNzJHV6pZYyEHt2ZnuV3MG8z2NNenC4i/8Kzttz7CjZiHSmsN5frhXhg17z3Zqjjhmz1A=="],
|
||||
|
||||
"@librechat/client/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="],
|
||||
|
||||
"@librechat/frontend/@react-spring/web": ["@react-spring/web@9.7.5", "", { "dependencies": { "@react-spring/animated": "~9.7.5", "@react-spring/core": "~9.7.5", "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ=="],
|
||||
|
|
@ -5854,11 +5866,11 @@
|
|||
|
||||
"@sinonjs/samsam/type-detect": ["type-detect@4.1.0", "", {}, "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw=="],
|
||||
|
||||
"@smithy/abort-controller/@smithy/types": ["@smithy/types@4.13.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g=="],
|
||||
"@smithy/abort-controller/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
"@smithy/config-resolver/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
"@smithy/eventstream-codec/@smithy/types": ["@smithy/types@4.13.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g=="],
|
||||
"@smithy/eventstream-codec/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
"@smithy/eventstream-serde-browser/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
|
|
@ -5866,8 +5878,6 @@
|
|||
|
||||
"@smithy/eventstream-serde-node/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
"@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.11", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w=="],
|
||||
|
||||
"@smithy/eventstream-serde-universal/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
"@smithy/hash-blob-browser/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
|
@ -5898,7 +5908,7 @@
|
|||
|
||||
"@smithy/protocol-http/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
"@smithy/querystring-builder/@smithy/types": ["@smithy/types@4.13.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g=="],
|
||||
"@smithy/querystring-builder/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
"@smithy/querystring-parser/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
|
|
@ -5930,8 +5940,6 @@
|
|||
|
||||
"@smithy/util-stream/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
"@smithy/util-waiter/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
|
||||
|
||||
"@smithy/util-waiter/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
|
||||
|
||||
"@tanstack/match-sorter-utils/remove-accents": ["remove-accents@0.4.2", "", {}, "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="],
|
||||
|
|
@ -6268,6 +6276,8 @@
|
|||
|
||||
"jest-runner/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
|
||||
|
||||
"jest-runner/source-map-support": ["source-map-support@0.5.13", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w=="],
|
||||
|
||||
"jest-runtime/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
|
||||
|
||||
"jest-runtime/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
|
||||
|
|
@ -6326,8 +6336,6 @@
|
|||
|
||||
"langsmith/p-queue": ["p-queue@6.6.2", "", { "dependencies": { "eventemitter3": "^4.0.4", "p-timeout": "^3.2.0" } }, "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ=="],
|
||||
|
||||
"launder/dayjs": ["dayjs@1.11.21", "", {}, "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA=="],
|
||||
|
||||
"ldapauth-fork/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
|
||||
|
||||
"lint-staged/chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="],
|
||||
|
|
@ -6350,14 +6358,14 @@
|
|||
|
||||
"memorystore/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
||||
|
||||
"mermaid/dayjs": ["dayjs@1.11.21", "", {}, "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA=="],
|
||||
|
||||
"micromark/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
||||
|
||||
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
|
||||
"miller-rabin/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
|
||||
|
||||
"minimatch/brace-expansion": ["brace-expansion@1.1.18", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw=="],
|
||||
|
||||
"mlly/acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
|
||||
|
||||
"monaco-editor/dompurify": ["dompurify@3.4.8", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-yb1cEmaOum7wFvOCSQxyfgVlv5D47Rc30iZWoMpbDIWTnJ6grDDQyu2KFJzB2k7u0pMuJcQ1zphH//fFnw2tjQ=="],
|
||||
|
|
@ -6370,8 +6378,6 @@
|
|||
|
||||
"mongodb-memory-server-core/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
||||
|
||||
"mongodb-memory-server-core/yauzl": ["yauzl@3.4.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw=="],
|
||||
|
||||
"mongoose/mongodb": ["mongodb@6.20.0", "", { "dependencies": { "@mongodb-js/saslprep": "^1.3.0", "bson": "^6.10.4", "mongodb-connection-string-url": "^3.0.2" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", "snappy": "^7.3.2", "socks": "^2.7.1" }, "optionalPeers": ["@aws-sdk/credential-providers", "@mongodb-js/zstd", "gcp-metadata", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ=="],
|
||||
|
||||
"mquery/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
||||
|
|
@ -6552,8 +6558,6 @@
|
|||
|
||||
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
|
||||
|
||||
"terser/source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
|
||||
|
||||
"test-exclude/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
|
||||
|
||||
"to-buffer/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
|
||||
|
|
@ -6670,12 +6674,6 @@
|
|||
|
||||
"@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.11", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g=="],
|
||||
|
||||
"@aws-sdk/client-s3/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
|
||||
|
||||
"@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
|
||||
|
||||
"@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
|
||||
|
||||
"@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.10", "", { "dependencies": { "@smithy/types": "^4.13.0", "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" } }, "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA=="],
|
||||
|
||||
"@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/core": ["@smithy/core@3.23.9", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.12", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ=="],
|
||||
|
|
@ -6952,6 +6950,8 @@
|
|||
|
||||
"@babel/preset-typescript/@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
|
||||
|
||||
"@eslint/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.18", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw=="],
|
||||
|
||||
"@firebase/firestore/@grpc/grpc-js/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
|
||||
|
||||
"@google/genai/google-auth-library/gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="],
|
||||
|
|
@ -7046,8 +7046,6 @@
|
|||
|
||||
"@langchain/google-gauth/google-auth-library/gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
|
||||
|
||||
"@langchain/langgraph-checkpoint-mongodb/mongodb/@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.4.13", "", { "dependencies": { "sparse-bitfield": "^3.0.3" } }, "sha512-E3Sv4eCYAlKYUTx8S3ioQcDUscOif+8zZ5OnW1IzJ+Tt+EO+ke8mn+Y3FX6N1H79picwbdOavVOb1jPi2EOyrg=="],
|
||||
|
||||
"@librechat/agents/@opentelemetry/sdk-node/@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.220.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-CmVa4ImJ+ynfrPMNaAXHET6Bhb44SwzmfyVJFq9ni2jgXJR/l7C6gfVFddNmHP+ZOkP9cf4f9DBe68qVLTHc9w=="],
|
||||
|
||||
"@librechat/agents/@opentelemetry/sdk-node/@opentelemetry/configuration": ["@opentelemetry/configuration@0.220.0", "", { "dependencies": { "@opentelemetry/core": "2.9.0", "yaml": "^2.8.3" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0" } }, "sha512-glfIVKnZevRin8fY/9uES/mhRtMT1lGINLHc9MIo5fTQZXswEEHamJtgjv4MTtzgnhHGC92mIS/0lzAUZMyE0w=="],
|
||||
|
|
@ -7096,88 +7094,6 @@
|
|||
|
||||
"@librechat/agents/@opentelemetry/sdk-node/@opentelemetry/sdk-trace-node": ["@opentelemetry/sdk-trace-node@2.9.0", "", { "dependencies": { "@opentelemetry/context-async-hooks": "2.9.0", "@opentelemetry/core": "2.9.0", "@opentelemetry/sdk-trace-base": "2.9.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-ec9a7ps37huy5itYk0MalaZdSLlM6AXWp/FhtEjgMpp5leEGojBDvAl/UWttQnkMZOvFHKzRESn8TD3yKTF5nQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core": ["@aws-sdk/core@3.973.22", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws-sdk/xml-builder": "^3.972.14", "@smithy/core": "^3.23.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-lY6g5L95jBNgOUitUhfV2N/W+i08jHEl3xuLODYSQH5Sf50V+LkVYBSyZRLtv2RyuXZXiV7yQ+acpswK1tlrOA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.23", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.20", "@aws-sdk/credential-provider-http": "^3.972.22", "@aws-sdk/credential-provider-ini": "^3.972.22", "@aws-sdk/credential-provider-process": "^3.972.20", "@aws-sdk/credential-provider-sso": "^3.972.22", "@aws-sdk/credential-provider-web-identity": "^3.972.22", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-U8tyLbLOZItuVWTH0ay9gWo4xMqZwqQbg1oMzdU4FQSkTpqXemm4X0uoKBR6llqAStgBp30ziKFJHTA43l4qMw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-2IrLrOruRr1NhTK0vguBL1gCWv1pu4bf4KaqpsA+/vCJpFEbvXFawn71GvCzk1wyjnDUsemtKypqoKGv4cSGbA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-eventstream": ["@aws-sdk/middleware-eventstream@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-r+oP+tbCxgqXVC3pu3MUVePgSY0ILMjA+aEwOosS77m3/DRbtvHrHwqvMcw+cjANMeGzJ+i0ar+n77KXpRA8RQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.23", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-retry": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-HQu8QoqGZZTvg0Spl9H39QTsSMFwgu+8yz/QGKndXFLk9FZMiCiIgBCVlTVKMDvVbgqIzD9ig+/HmXsIL2Rb+g=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket": ["@aws-sdk/middleware-websocket@3.972.13", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-format-url": "^3.972.8", "@smithy/eventstream-codec": "^4.2.12", "@smithy/eventstream-serde-browser": "^4.2.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Gp6EWIqHX5wmsOR5ZxWyyzEU8P0xBdSxkm6VHEwXwBqScKZ7QWRoj6ZmHpr+S44EYb5tuzGya4ottsogSu2W3A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/config-resolver": "^4.4.11", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-1eD4uhTDeambO/PNIDVG19A6+v4NdD7xzwLHDutHsUqz0B+i661MwQB2eYO4/crcCvCiQG4SRm1k81k54FEIvw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1013.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-IL1c54UvbuERrs9oLm5rvkzMciwhhpn1FL0SlC3XUMoLlFhdBsWJgQKK8O5fsQLxbFVqjbjFx9OBkrn44X9PHw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/types": ["@aws-sdk/types@3.973.6", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.5", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-endpoints": "^3.3.3", "tslib": "^2.6.2" } }, "sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.9", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/types": "^3.973.6", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-jeFqqp8KD/P5O+qeKxyGeu7WEVIZFNprnkaDjGmBOjwxYwafCBhpxTgV1TlW6L8e76Vh/siNylNmN/OmSIFBUQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/config-resolver": ["@smithy/config-resolver@4.4.13", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/core": ["@smithy/core@3.23.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.15", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/hash-node": ["@smithy/hash-node@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.27", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-serde": "^4.2.15", "@smithy/node-config-provider": "^4.3.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-T3TFfUgXQlpcg+UdzcAISdZpj4Z+XECZ/cefgA6wLBd6V4lRi0svN2hBouN/be9dXQ31X4sLWz3fAQDf+nt6BA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.44", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/service-error-classification": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-Y1Rav7m5CFRPQyM4CI0koD/bXjyjJu3EQxZZhtLGD88WIrBrQ7kqXM96ncd6rYnojwOo/u9MXu57JrEvu/nLrA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.15", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-ExYhcltZSli0pgAKOpQQe1DLFBLryeZ22605y/YS+mQpdNWekum9Ujb/jMKfJKgjtz1AZldtwA/wCYuKJgjjlg=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.12", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.12.7", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-endpoint": "^4.4.27", "@smithy/middleware-stack": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-stream": "^4.5.20", "tslib": "^2.6.2" } }, "sha512-q3gqnwml60G44FECaEEsdQMplYhDMZYCtYhMCzadCnRnnHIobZJjegmdoUo6ieLQlPUzvrMdIJUpx6DoPmzANQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/types": ["@smithy/types@4.13.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/url-parser": ["@smithy/url-parser@4.2.12", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.43", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Qd/0wCKMaXxev/z00TvNzGCH2jlKKKxXP1aDxB6oKwSQthe3Og2dMhSayGCnsma1bK/kQX1+X7SMP99t6FgiiQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.47", "", { "dependencies": { "@smithy/config-resolver": "^4.4.13", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-qSRbYp1EQ7th+sPFuVcVO05AE0QH635hycdEXlpzIahqHHf2Fyd/Zl+8v0XYMJ3cgDVPa0lkMefU7oNUjAP+DQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.3", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-retry": ["@smithy/util-retry@4.2.12", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-1zopLDUEOwumjcHdJ1mwBHddubYF8GMQvstVCLC54Y46rqoHwlIU+8ZzUeaBcD+WCJHyDGSeZ2ml9YSe9aqcoQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-stream": ["@smithy/util-stream@4.5.20", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-4yXLm5n/B5SRBR2p8cZ90Sbv4zL4NKsgxdzCzp/83cXw2KxLEumt5p+GAVyRNZgQOSrzXn9ARpO0lUe8XSlSDw=="],
|
||||
|
||||
"@librechat/backend/@smithy/node-http-handler/@smithy/protocol-http": ["@smithy/protocol-http@5.3.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw=="],
|
||||
|
||||
"@librechat/backend/@smithy/node-http-handler/@smithy/types": ["@smithy/types@4.13.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g=="],
|
||||
|
||||
"@librechat/frontend/@react-spring/web/@react-spring/animated": ["@react-spring/animated@9.7.5", "", { "dependencies": { "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg=="],
|
||||
|
||||
"@librechat/frontend/@react-spring/web/@react-spring/core": ["@react-spring/core@9.7.5", "", { "dependencies": { "@react-spring/animated": "~9.7.5", "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w=="],
|
||||
|
|
@ -7334,12 +7250,6 @@
|
|||
|
||||
"@rollup/plugin-babel/@babel/helper-module-imports/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="],
|
||||
|
||||
"@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
|
||||
|
||||
"@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
|
||||
|
||||
"@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
|
||||
|
||||
"@testing-library/dom/@babel/code-frame/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
|
||||
|
||||
"@testing-library/dom/pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
|
||||
|
|
@ -7388,6 +7298,8 @@
|
|||
|
||||
"@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="],
|
||||
|
||||
"@typescript-eslint/utils/@typescript-eslint/typescript-estree/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
||||
|
||||
"@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
|
|
@ -7438,8 +7350,16 @@
|
|||
|
||||
"data-urls/whatwg-url/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
|
||||
|
||||
"eslint-plugin-import/minimatch/brace-expansion": ["brace-expansion@1.1.18", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw=="],
|
||||
|
||||
"eslint-plugin-jsx-a11y/minimatch/brace-expansion": ["brace-expansion@1.1.18", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw=="],
|
||||
|
||||
"eslint-plugin-react/minimatch/brace-expansion": ["brace-expansion@1.1.18", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw=="],
|
||||
|
||||
"eslint/@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"eslint/minimatch/brace-expansion": ["brace-expansion@1.1.18", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw=="],
|
||||
|
||||
"expect/jest-message-util/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
|
||||
|
||||
"expect/jest-message-util/@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
|
||||
|
|
@ -7464,6 +7384,8 @@
|
|||
|
||||
"gcp-metadata/gaxios/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
|
||||
|
||||
"glob/minimatch/brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="],
|
||||
|
||||
"google-auth-library/gcp-metadata/google-logging-utils": ["google-logging-utils@0.0.2", "", {}, "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ=="],
|
||||
|
||||
"hast-util-from-html-isomorphic/@types/hast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
|
||||
|
|
@ -7516,6 +7438,8 @@
|
|||
|
||||
"istanbul-lib-report/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"jake/minimatch/brace-expansion": ["brace-expansion@1.1.18", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw=="],
|
||||
|
||||
"jest-changed-files/execa/human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
|
||||
|
||||
"jest-changed-files/execa/npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
|
||||
|
|
@ -7662,18 +7586,16 @@
|
|||
|
||||
"mongodb-connection-string-url/whatwg-url/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
|
||||
|
||||
"mongodb-memory-server-core/mongodb/@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.4.13", "", { "dependencies": { "sparse-bitfield": "^3.0.3" } }, "sha512-E3Sv4eCYAlKYUTx8S3ioQcDUscOif+8zZ5OnW1IzJ+Tt+EO+ke8mn+Y3FX6N1H79picwbdOavVOb1jPi2EOyrg=="],
|
||||
|
||||
"mongodb-memory-server-core/mongodb/bson": ["bson@7.3.1", "", {}, "sha512-h/C0qe6857pQhcSJHLfsR1uYGj98Ge3wKAD3Ed9KqH3wcVh+BM4Jq4xISD7vs9OPuT07n+q3QQVjslJ286j6ag=="],
|
||||
|
||||
"mongodb-memory-server-core/mongodb/mongodb-connection-string-url": ["mongodb-connection-string-url@7.0.2", "", { "dependencies": { "@types/whatwg-url": "^13.0.0", "whatwg-url": "^14.1.0" } }, "sha512-ZoS07RoFqpKYQwAk59qmrx8+jJHNHU30UjlU96QktiGn1ltvDr+vCznLX5DiUBLEpMAHatHNWV1nM/74ul66kA=="],
|
||||
|
||||
"mongoose/mongodb/@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.4.13", "", { "dependencies": { "sparse-bitfield": "^3.0.3" } }, "sha512-E3Sv4eCYAlKYUTx8S3ioQcDUscOif+8zZ5OnW1IzJ+Tt+EO+ke8mn+Y3FX6N1H79picwbdOavVOb1jPi2EOyrg=="],
|
||||
|
||||
"multer/type-is/media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="],
|
||||
|
||||
"multer/type-is/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
||||
|
||||
"nodemon/minimatch/brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="],
|
||||
|
||||
"parse-json/@babel/code-frame/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
|
||||
|
||||
"pbkdf2/ripemd160/hash-base": ["hash-base@2.0.2", "", { "dependencies": { "inherits": "^2.0.1" } }, "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw=="],
|
||||
|
|
@ -7728,6 +7650,8 @@
|
|||
|
||||
"tailwindcss/postcss-load-config/lilconfig": ["lilconfig@3.0.0", "", {}, "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g=="],
|
||||
|
||||
"test-exclude/minimatch/brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="],
|
||||
|
||||
"typescript-eslint/@typescript-eslint/eslint-plugin/@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
|
||||
|
||||
"typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.65.0", "", { "dependencies": { "@typescript-eslint/types": "8.65.0", "@typescript-eslint/visitor-keys": "8.65.0" } }, "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg=="],
|
||||
|
|
@ -8132,64 +8056,6 @@
|
|||
|
||||
"@librechat/agents/@opentelemetry/sdk-node/@opentelemetry/otlp-grpc-exporter-base/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.220.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.220.0", "@opentelemetry/core": "2.9.0", "@opentelemetry/resources": "2.9.0", "@opentelemetry/sdk-logs": "0.220.0", "@opentelemetry/sdk-metrics": "2.9.0", "@opentelemetry/sdk-trace": "2.9.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-lXGrv7KXZ0gNH9SVNUaa6vv6phVYGvJxfXAlMbzbakiXru75f5MZl8Z7oqiMMQD77riVHJCFlQvbZs/VVN2/4A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.14", "", { "dependencies": { "@smithy/types": "^4.13.1", "fast-xml-parser": "5.5.6", "tslib": "^2.6.2" } }, "sha512-G/Yd8Bnnyh8QrqLf8jWJbixEnScUFW24e/wOBGYdw1Cl4r80KX/DvHyM2GVZ2vTp7J4gTEr8IXJlTadA8+UfuQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.12", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.20", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-vI0QN96DFx3g9AunfOWF3CS4cMkqFiR/WM/FyP9QHr5rZ2dKPkYwP3tCgAOvGuu9CXI7dC1vU2FVUuZ+tfpNvQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/util-stream": "^4.5.20", "tslib": "^2.6.2" } }, "sha512-aS/81smalpe7XDnuQfOq4LIPuaV2PRKU2aMTrHcqO5BD4HwO5kESOHNcec2AYfBtLtIDqgF6RXisgBnfK/jt0w=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/credential-provider-env": "^3.972.20", "@aws-sdk/credential-provider-http": "^3.972.22", "@aws-sdk/credential-provider-login": "^3.972.22", "@aws-sdk/credential-provider-process": "^3.972.20", "@aws-sdk/credential-provider-sso": "^3.972.22", "@aws-sdk/credential-provider-web-identity": "^3.972.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-rpF8fBT0LllMDp78s62aL2A/8MaccjyJ0ORzqu+ZADeECLSrrCWIeeXsuRam+pxiAMkI1uIyDZJmgLGdadkPXw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.20", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-QRfk7GbA4/HDRjhP3QYR6QBr/QKreVoOzvvlRHnOuGgYJkeoPgPY3LAI1kK1ZMgZ4hH9KiGp757/ntol+INAig=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/token-providers": "3.1013.0", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-4vqlSaUbBj4aNPVKfB6yXuIQ2Z2mvLfIGba2OzzF6zUkN437/PGWsxBU2F8QPSFHti6seckvyCXidU3H+R8NvQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-/wN1CYg2rVLhW8/jLxMWacQrkpaynnL+4j/Z+e6X1PfoE6NiC0BeOw3i0JmtZrKun85wNV5GmspvuWJihfeeUw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-recursion-detection/@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.2", "", {}, "sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-J6DS9oocrgxM8xlUTTmQOuwRF6rnAGEujAN9SAzllcrQmwn5iJ58ogxy3SEhD0Q7JZvlA5jvIXBkpQRqEqlE9A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4": ["@smithy/signature-v4@5.3.12", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.12", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.22", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.9", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.26", "@smithy/middleware-retry": "^4.4.43", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.42", "@smithy/util-defaults-mode-node": "^4.2.45", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-KLdQGJPSm98uLINolQ0Tol8OAbk7g0Y7zplHJ1K83vbMIH13aoCvR6Tho66xueW4l4aZlEgVGLWBnD8ifUMsGQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.12", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.12", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1" } }, "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1" } }, "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ=="],
|
||||
|
||||
"@librechat/frontend/@react-spring/web/@react-spring/shared/@react-spring/rafz": ["@react-spring/rafz@9.7.5", "", {}, "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw=="],
|
||||
|
||||
"@librechat/frontend/@testing-library/jest-dom/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
|
|
@ -8240,6 +8106,8 @@
|
|||
|
||||
"@rollup/plugin-babel/@babel/helper-module-imports/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
|
||||
|
||||
"@unrs/resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
|
||||
|
||||
"babel-plugin-transform-import-meta/@babel/template/@babel/code-frame/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
|
||||
|
|
@ -8272,6 +8140,8 @@
|
|||
|
||||
"gcp-metadata/gaxios/https-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
||||
|
||||
"glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
|
||||
|
||||
"hast-util-from-html-isomorphic/unist-util-remove-position/unist-util-visit/unist-util-is": ["unist-util-is@5.2.1", "", { "dependencies": { "@types/unist": "^2.0.0" } }, "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw=="],
|
||||
|
||||
"hast-util-from-html-isomorphic/unist-util-remove-position/unist-util-visit/unist-util-visit-parents": ["unist-util-visit-parents@5.1.3", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" } }, "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg=="],
|
||||
|
|
@ -8346,6 +8216,8 @@
|
|||
|
||||
"multer/type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
||||
|
||||
"nodemon/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
|
||||
|
||||
"pkg-dir/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
|
||||
|
||||
"rehype-highlight/unified/vfile/unist-util-stringify-position": ["unist-util-stringify-position@3.0.3", "", { "dependencies": { "@types/unist": "^2.0.0" } }, "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg=="],
|
||||
|
|
@ -8356,6 +8228,8 @@
|
|||
|
||||
"sucrase/glob/path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
|
||||
|
||||
"test-exclude/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
|
||||
|
||||
"typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.65.0", "", {}, "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg=="],
|
||||
|
||||
"typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/types": ["@typescript-eslint/types@8.65.0", "", {}, "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg=="],
|
||||
|
|
@ -8522,14 +8396,6 @@
|
|||
|
||||
"@librechat/agents/@opentelemetry/sdk-node/@opentelemetry/instrumentation/import-in-the-middle/cjs-module-lexer": ["cjs-module-lexer@2.2.0", "", {}, "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-u33CO9zeNznlVSg9tWTCRYxaGkqr1ufU6qeClpmzAabXZa8RZxQoVXxL5T53oZJFzQYj+FImORCSsi7H7B77gQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.12", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.22", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.9", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.26", "@smithy/middleware-retry": "^4.4.43", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.42", "@smithy/util-defaults-mode-node": "^4.2.45", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-KLdQGJPSm98uLINolQ0Tol8OAbk7g0Y7zplHJ1K83vbMIH13aoCvR6Tho66xueW4l4aZlEgVGLWBnD8ifUMsGQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.12", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.22", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.9", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.26", "@smithy/middleware-retry": "^4.4.43", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.42", "@smithy/util-defaults-mode-node": "^4.2.45", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-KLdQGJPSm98uLINolQ0Tol8OAbk7g0Y7zplHJ1K83vbMIH13aoCvR6Tho66xueW4l4aZlEgVGLWBnD8ifUMsGQ=="],
|
||||
|
||||
"@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.12", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.22", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.9", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.26", "@smithy/middleware-retry": "^4.4.43", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.42", "@smithy/util-defaults-mode-node": "^4.2.45", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-KLdQGJPSm98uLINolQ0Tol8OAbk7g0Y7zplHJ1K83vbMIH13aoCvR6Tho66xueW4l4aZlEgVGLWBnD8ifUMsGQ=="],
|
||||
|
||||
"@librechat/frontend/@testing-library/jest-dom/chalk/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"@mcp-ui/client/@modelcontextprotocol/sdk/express/body-parser/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { useState, useMemo } from 'react';
|
||||
import { ChevronDown } from 'lucide-react';
|
||||
import { Tools } from 'librechat-data-provider';
|
||||
import { UIResourceRenderer } from '@mcp-ui/client';
|
||||
import type { TAttachment, UIResource } from 'librechat-data-provider';
|
||||
import UIResourceRenderer, { isSupportedUIResource } from '~/components/MCPUIResource/Renderer';
|
||||
import { useOptionalMessagesOperations } from '~/Providers';
|
||||
import { useLocalize, useExpandCollapse } from '~/hooks';
|
||||
import UIResourceCarousel from './UIResourceCarousel';
|
||||
import { handleUIAction, cn } from '~/utils';
|
||||
import { OutputRenderer } from './ToolOutput';
|
||||
import { handleUIAction, cn } from '~/utils';
|
||||
|
||||
function isSimpleObject(obj: unknown): obj is Record<string, string | number | boolean | null> {
|
||||
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
|
||||
|
|
@ -126,7 +126,8 @@ export default function ToolCallInfo({
|
|||
?.filter((attachment) => attachment.type === Tools.ui_resources)
|
||||
.flatMap((attachment) => {
|
||||
return attachment[Tools.ui_resources] as UIResource[];
|
||||
}) ?? [];
|
||||
})
|
||||
.filter(isSupportedUIResource) ?? [];
|
||||
|
||||
return (
|
||||
<div className="w-full px-3 py-3.5">
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Button } from '@librechat/client';
|
||||
import { UIResourceRenderer } from '@mcp-ui/client';
|
||||
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
||||
import type { UIResource } from 'librechat-data-provider';
|
||||
import UIResourceRenderer, { isSupportedUIResource } from '~/components/MCPUIResource/Renderer';
|
||||
import { useOptionalMessagesOperations } from '~/Providers';
|
||||
import { handleUIAction } from '~/utils';
|
||||
import { useLocalize } from '~/hooks';
|
||||
|
|
@ -18,6 +18,10 @@ const UIResourceCarousel: React.FC<UIResourceCarouselProps> = React.memo(({ uiRe
|
|||
const [isContainerHovered, setIsContainerHovered] = useState(false);
|
||||
const scrollContainerRef = React.useRef<HTMLDivElement>(null);
|
||||
const { ask } = useOptionalMessagesOperations();
|
||||
const supportedUIResources = React.useMemo(
|
||||
() => uiResources.filter(isSupportedUIResource),
|
||||
[uiResources],
|
||||
);
|
||||
|
||||
const handleScroll = React.useCallback(() => {
|
||||
if (!scrollContainerRef.current) return;
|
||||
|
|
@ -49,12 +53,24 @@ const UIResourceCarousel: React.FC<UIResourceCarouselProps> = React.memo(({ uiRe
|
|||
handleScroll();
|
||||
return () => container.removeEventListener('scroll', handleScroll);
|
||||
}
|
||||
}, [handleScroll]);
|
||||
}, [handleScroll, supportedUIResources.length]);
|
||||
|
||||
if (uiResources.length === 0) {
|
||||
if (supportedUIResources.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (supportedUIResources.length === 1) {
|
||||
return (
|
||||
<UIResourceRenderer
|
||||
resource={supportedUIResources[0]}
|
||||
onUIAction={async (result) => handleUIAction(result, ask)}
|
||||
htmlProps={{
|
||||
autoResizeIframe: { width: true, height: true },
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="relative mb-4 pt-3"
|
||||
|
|
@ -91,7 +107,7 @@ const UIResourceCarousel: React.FC<UIResourceCarouselProps> = React.memo(({ uiRe
|
|||
ref={scrollContainerRef}
|
||||
className="hide-scrollbar flex gap-4 overflow-x-auto scroll-smooth"
|
||||
>
|
||||
{uiResources.map((uiResource, index) => {
|
||||
{supportedUIResources.map((uiResource, index) => {
|
||||
const height = 360;
|
||||
const width = 230;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,8 +64,10 @@ describe('ToolCallInfo', () => {
|
|||
describe('ui_resources from attachments', () => {
|
||||
it('should render single ui_resource from attachments', () => {
|
||||
const uiResource = {
|
||||
type: 'text',
|
||||
data: 'Test resource',
|
||||
resourceId: 'resource-1',
|
||||
uri: 'ui://test/resource-1',
|
||||
mimeType: 'text/html',
|
||||
text: 'Test resource',
|
||||
};
|
||||
|
||||
const attachments: TAttachment[] = [
|
||||
|
|
@ -104,10 +106,25 @@ describe('ToolCallInfo', () => {
|
|||
toolCallId: 'tool1',
|
||||
conversationId: 'conv1',
|
||||
[Tools.ui_resources]: [
|
||||
{ type: 'text', data: 'Resource 1' },
|
||||
{ type: 'text', data: 'Resource 2' },
|
||||
{ type: 'text', data: 'Resource 3' },
|
||||
] as any,
|
||||
{
|
||||
resourceId: 'resource-1',
|
||||
uri: 'ui://test/resource-1',
|
||||
mimeType: 'text/html',
|
||||
text: 'Resource 1',
|
||||
},
|
||||
{
|
||||
resourceId: 'resource-2',
|
||||
uri: 'ui://test/resource-2',
|
||||
mimeType: 'text/html',
|
||||
text: 'Resource 2',
|
||||
},
|
||||
{
|
||||
resourceId: 'resource-3',
|
||||
uri: 'ui://test/resource-3',
|
||||
mimeType: 'text/html',
|
||||
text: 'Resource 3',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -117,9 +134,9 @@ describe('ToolCallInfo', () => {
|
|||
expect(UIResourceCarousel).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
uiResources: [
|
||||
{ type: 'text', data: 'Resource 1' },
|
||||
{ type: 'text', data: 'Resource 2' },
|
||||
{ type: 'text', data: 'Resource 3' },
|
||||
expect.objectContaining({ resourceId: 'resource-1' }),
|
||||
expect.objectContaining({ resourceId: 'resource-2' }),
|
||||
expect.objectContaining({ resourceId: 'resource-3' }),
|
||||
],
|
||||
}),
|
||||
expect.any(Object),
|
||||
|
|
@ -129,6 +146,65 @@ describe('ToolCallInfo', () => {
|
|||
expect(UIResourceRenderer).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders a single supported resource without carousel layout', () => {
|
||||
const attachments: TAttachment[] = [
|
||||
{
|
||||
type: Tools.ui_resources,
|
||||
messageId: 'msg1',
|
||||
toolCallId: 'tool1',
|
||||
conversationId: 'conv1',
|
||||
[Tools.ui_resources]: [
|
||||
{
|
||||
resourceId: 'blocked-resource',
|
||||
uri: 'ui://test/blocked',
|
||||
mimeType: 'application/vnd.mcp-ui.remote-dom+javascript',
|
||||
text: 'malicious script',
|
||||
},
|
||||
{
|
||||
resourceId: 'html-resource',
|
||||
uri: 'ui://test/html',
|
||||
mimeType: 'text/html',
|
||||
text: '<p>Supported</p>',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
render(<ToolCallInfo {...mockProps} attachments={attachments} />);
|
||||
|
||||
expect(UIResourceRenderer).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
resource: expect.objectContaining({ resourceId: 'html-resource' }),
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
expect(UIResourceCarousel).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('omits the resource section when every resource is blocked', () => {
|
||||
const attachments: TAttachment[] = [
|
||||
{
|
||||
type: Tools.ui_resources,
|
||||
messageId: 'msg1',
|
||||
toolCallId: 'tool1',
|
||||
conversationId: 'conv1',
|
||||
[Tools.ui_resources]: [
|
||||
{
|
||||
resourceId: 'blocked-resource',
|
||||
uri: 'ui://test/blocked',
|
||||
mimeType: 'text/uri-list',
|
||||
text: 'https://example.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
render(<ToolCallInfo input="" attachments={attachments} />);
|
||||
|
||||
expect(UIResourceRenderer).not.toHaveBeenCalled();
|
||||
expect(UIResourceCarousel).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle no attachments', () => {
|
||||
render(<ToolCallInfo {...mockProps} output="Some output" />);
|
||||
|
||||
|
|
@ -200,7 +276,14 @@ describe('ToolCallInfo', () => {
|
|||
messageId: 'msg123',
|
||||
toolCallId: 'tool456',
|
||||
conversationId: 'conv789',
|
||||
[Tools.ui_resources]: [{ type: 'text', data: 'Test' }] as any,
|
||||
[Tools.ui_resources]: [
|
||||
{
|
||||
resourceId: 'resource-1',
|
||||
uri: 'ui://test/resource-1',
|
||||
mimeType: 'text/html',
|
||||
text: 'Test',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -208,7 +291,7 @@ describe('ToolCallInfo', () => {
|
|||
|
||||
expect(UIResourceRenderer).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
resource: { type: 'text', data: 'Test' },
|
||||
resource: expect.objectContaining({ resourceId: 'resource-1', text: 'Test' }),
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
|
|
@ -241,7 +324,14 @@ describe('ToolCallInfo', () => {
|
|||
messageId: 'msg123',
|
||||
toolCallId: 'tool456',
|
||||
conversationId: 'conv789',
|
||||
[Tools.ui_resources]: [{ type: 'attachment', data: 'From attachments' }] as any,
|
||||
[Tools.ui_resources]: [
|
||||
{
|
||||
resourceId: 'attachment-resource',
|
||||
uri: 'ui://test/attachment-resource',
|
||||
mimeType: 'text/html',
|
||||
text: 'From attachments',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -259,7 +349,10 @@ describe('ToolCallInfo', () => {
|
|||
// Should use attachments, not output
|
||||
expect(UIResourceRenderer).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
resource: { type: 'attachment', data: 'From attachments' },
|
||||
resource: expect.objectContaining({
|
||||
resourceId: 'attachment-resource',
|
||||
text: 'From attachments',
|
||||
}),
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,27 @@
|
|||
import '@testing-library/jest-dom';
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import type { UIResource } from 'librechat-data-provider';
|
||||
import type { ComponentProps } from 'react';
|
||||
import UIResourceCarousel from '~/components/Chat/Messages/Content/UIResourceCarousel';
|
||||
import { handleUIAction } from '~/utils';
|
||||
|
||||
jest.mock(
|
||||
'@librechat/client',
|
||||
() => ({
|
||||
Button: ({
|
||||
variant: _variant,
|
||||
size: _size,
|
||||
...props
|
||||
}: ComponentProps<'button'> & { variant?: string; size?: string }) => <button {...props} />,
|
||||
}),
|
||||
{ virtual: true },
|
||||
);
|
||||
|
||||
jest.mock('~/hooks', () => ({
|
||||
useLocalize: () => (key: string) =>
|
||||
key === 'com_ui_scroll_left' ? 'Scroll left' : 'Scroll right',
|
||||
}));
|
||||
|
||||
// Mock the UIResourceRenderer component
|
||||
jest.mock('@mcp-ui/client', () => ({
|
||||
UIResourceRenderer: ({ resource, onUIAction }: any) => (
|
||||
|
|
@ -69,6 +87,43 @@ describe('UIResourceCarousel', () => {
|
|||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
|
||||
it('filters blocked resources before choosing a single-resource layout', () => {
|
||||
const { container } = render(
|
||||
<UIResourceCarousel
|
||||
uiResources={[
|
||||
{
|
||||
resourceId: 'blocked-resource',
|
||||
uri: 'ui://blocked',
|
||||
mimeType: 'application/vnd.mcp-ui.remote-dom+javascript',
|
||||
text: 'malicious script',
|
||||
},
|
||||
mockUIResources[0],
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getAllByTestId('ui-resource-renderer')).toHaveLength(1);
|
||||
expect(screen.getByText('Resource 1')).toBeInTheDocument();
|
||||
expect(container.querySelector('.hide-scrollbar')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders nothing when every resource is blocked', () => {
|
||||
const { container } = render(
|
||||
<UIResourceCarousel
|
||||
uiResources={[
|
||||
{
|
||||
resourceId: 'blocked-resource',
|
||||
uri: 'ui://blocked',
|
||||
mimeType: 'text/uri-list',
|
||||
text: 'https://example.com',
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
|
||||
it('renders all UI resources', () => {
|
||||
render(<UIResourceCarousel uiResources={mockUIResources} />);
|
||||
const renderers = screen.getAllByTestId('ui-resource-renderer');
|
||||
|
|
@ -141,6 +196,26 @@ describe('UIResourceCarousel', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('binds scrolling when a singleton becomes a carousel', async () => {
|
||||
const { container, rerender } = render(
|
||||
<UIResourceCarousel uiResources={mockUIResources.slice(0, 1)} />,
|
||||
);
|
||||
expect(container.querySelector('.hide-scrollbar')).not.toBeInTheDocument();
|
||||
|
||||
rerender(<UIResourceCarousel uiResources={mockUIResources.slice(0, 2)} />);
|
||||
const scrollContainer = container.querySelector('.hide-scrollbar');
|
||||
Object.defineProperty(scrollContainer, 'scrollLeft', {
|
||||
configurable: true,
|
||||
value: 200,
|
||||
});
|
||||
|
||||
fireEvent.scroll(scrollContainer!);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByLabelText('Scroll left')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('hides right arrow when scrolled to end', async () => {
|
||||
const { container } = render(<UIResourceCarousel uiResources={mockUIResources} />);
|
||||
const scrollContainer = container.querySelector('.hide-scrollbar');
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { UIResourceRenderer } from '@mcp-ui/client';
|
||||
import { useOptionalMessagesConversation, useOptionalMessagesOperations } from '~/Providers';
|
||||
import { useConversationUIResources } from '~/hooks/Messages/useConversationUIResources';
|
||||
import UIResourceRenderer, { isSupportedUIResource } from './Renderer';
|
||||
import { handleUIAction } from '~/utils';
|
||||
import { useLocalize } from '~/hooks';
|
||||
|
||||
|
|
@ -34,6 +34,10 @@ export function MCPUIResource(props: MCPUIResourceProps) {
|
|||
);
|
||||
}
|
||||
|
||||
if (!isSupportedUIResource(uiResource)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return (
|
||||
<span className="mx-1 inline-block w-full align-middle">
|
||||
|
|
@ -42,7 +46,6 @@ export function MCPUIResource(props: MCPUIResourceProps) {
|
|||
onUIAction={async (result) => handleUIAction(result, ask)}
|
||||
htmlProps={{
|
||||
autoResizeIframe: { width: true, height: true },
|
||||
sandboxPermissions: 'allow-popups',
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
|
|
|
|||
47
client/src/components/MCPUIResource/Renderer.tsx
Normal file
47
client/src/components/MCPUIResource/Renderer.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { UIResourceRenderer as LegacyUIResourceRenderer } from '@mcp-ui/client';
|
||||
import type { UIResource } from 'librechat-data-provider';
|
||||
import type { ComponentProps } from 'react';
|
||||
|
||||
type LegacyRendererProps = ComponentProps<typeof LegacyUIResourceRenderer>;
|
||||
|
||||
type UIResourceRendererProps = Omit<
|
||||
LegacyRendererProps,
|
||||
'resource' | 'remoteDomProps' | 'supportedContentTypes'
|
||||
> & {
|
||||
resource: UIResource;
|
||||
};
|
||||
|
||||
export function isSupportedUIResource(
|
||||
resource: UIResource | null | undefined,
|
||||
): resource is UIResource {
|
||||
return (
|
||||
typeof resource?.mimeType === 'string' &&
|
||||
resource.mimeType.split(';', 1)[0].trim().toLowerCase() === 'text/html'
|
||||
);
|
||||
}
|
||||
|
||||
/** Restricts legacy MCP-UI rendering to sandboxed inline HTML resources. */
|
||||
export default function UIResourceRenderer({
|
||||
resource,
|
||||
htmlProps,
|
||||
...props
|
||||
}: UIResourceRendererProps) {
|
||||
if (!isSupportedUIResource(resource)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const safeResource = { ...resource };
|
||||
const safeHtmlProps = { ...htmlProps };
|
||||
delete safeResource.contentType;
|
||||
safeResource.mimeType = 'text/html';
|
||||
delete safeHtmlProps.sandboxPermissions;
|
||||
|
||||
return (
|
||||
<LegacyUIResourceRenderer
|
||||
{...props}
|
||||
resource={safeResource}
|
||||
htmlProps={safeHtmlProps}
|
||||
supportedContentTypes={['rawHtml']}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,19 +1,23 @@
|
|||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { MCPUIResource } from '../MCPUIResource';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import {
|
||||
useMessageContext,
|
||||
useOptionalMessagesConversation,
|
||||
useOptionalMessagesOperations,
|
||||
} from '~/Providers';
|
||||
import { useLocalize } from '~/hooks';
|
||||
import { MCPUIResource } from '../MCPUIResource';
|
||||
import { handleUIAction } from '~/utils';
|
||||
import { useLocalize } from '~/hooks';
|
||||
|
||||
// Mock dependencies
|
||||
jest.mock('~/Providers');
|
||||
jest.mock('~/hooks');
|
||||
jest.mock('~/utils');
|
||||
jest.mock('~/Providers', () => ({
|
||||
useMessageContext: jest.fn(),
|
||||
useOptionalMessagesConversation: jest.fn(),
|
||||
useOptionalMessagesOperations: jest.fn(),
|
||||
}));
|
||||
jest.mock('~/hooks', () => ({ useLocalize: jest.fn() }));
|
||||
jest.mock('~/utils', () => ({ handleUIAction: jest.fn() }));
|
||||
|
||||
jest.mock('@mcp-ui/client', () => ({
|
||||
UIResourceRenderer: ({ resource, onUIAction }: any) => (
|
||||
|
|
@ -141,6 +145,34 @@ describe('MCPUIResource', () => {
|
|||
expect(screen.getByText('UI resource resource-1 not found')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should omit a referenced resource with an unsupported MIME type', () => {
|
||||
currentTestMessages = [
|
||||
{
|
||||
messageId: 'msg123',
|
||||
attachments: [
|
||||
{
|
||||
type: 'ui_resources',
|
||||
ui_resources: [
|
||||
{
|
||||
resourceId: 'blocked-resource',
|
||||
uri: 'ui://test/blocked',
|
||||
mimeType: 'application/vnd.mcp-ui.remote-dom+javascript',
|
||||
text: 'malicious script',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const { container } = renderWithRecoil(
|
||||
<MCPUIResource node={{ properties: { resourceId: 'blocked-resource' } }} />,
|
||||
);
|
||||
|
||||
expect(container.firstChild).toBeNull();
|
||||
expect(screen.queryByTestId('ui-resource-renderer')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should resolve resources by resourceId across conversation messages', () => {
|
||||
mockUseMessageContext.mockReturnValue({ messageId: 'msg-current' } as any);
|
||||
currentTestMessages = [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
import { render, screen } from '@testing-library/react';
|
||||
import { UIResourceRenderer as LegacyUIResourceRenderer } from '@mcp-ui/client';
|
||||
import type { UIResource } from 'librechat-data-provider';
|
||||
import UIResourceRenderer from '../Renderer';
|
||||
|
||||
jest.mock('@mcp-ui/client', () => ({
|
||||
UIResourceRenderer: jest.fn(({ resource }) => (
|
||||
<div data-testid="legacy-ui-resource" data-mime-type={resource.mimeType} />
|
||||
)),
|
||||
}));
|
||||
|
||||
const mockLegacyRenderer = LegacyUIResourceRenderer as jest.MockedFunction<
|
||||
typeof LegacyUIResourceRenderer
|
||||
>;
|
||||
|
||||
describe('UIResourceRenderer', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it.each([
|
||||
'application/vnd.mcp-ui.remote-dom+javascript',
|
||||
'application/vnd.mcp-ui.remote-dom',
|
||||
'text/uri-list',
|
||||
])('blocks unsafe legacy MIME type %s', (mimeType) => {
|
||||
const resource: UIResource = {
|
||||
resourceId: 'unsafe-resource',
|
||||
uri: 'ui://unsafe',
|
||||
mimeType,
|
||||
text: "root.innerHTML='<img src=x onerror=alert(window.origin)>'",
|
||||
};
|
||||
|
||||
const { container } = render(<UIResourceRenderer resource={resource} />);
|
||||
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
expect(mockLegacyRenderer).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('blocks malformed non-string MIME values', () => {
|
||||
const resource: UIResource = {
|
||||
resourceId: 'malformed-resource',
|
||||
uri: 'ui://malformed',
|
||||
mimeType: 1 as unknown as string,
|
||||
text: '<p>Malformed resource</p>',
|
||||
};
|
||||
|
||||
const { container } = render(<UIResourceRenderer resource={resource} />);
|
||||
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
expect(mockLegacyRenderer).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('forces text/html through the raw HTML renderer without popup permissions', () => {
|
||||
const resource: UIResource = {
|
||||
resourceId: 'html-resource',
|
||||
uri: 'ui://html',
|
||||
mimeType: 'text/html',
|
||||
contentType: 'remoteDom',
|
||||
text: '<p>Safe iframe content</p>',
|
||||
};
|
||||
|
||||
render(
|
||||
<UIResourceRenderer
|
||||
resource={resource}
|
||||
htmlProps={{ sandboxPermissions: 'allow-popups allow-same-origin' }}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('legacy-ui-resource')).toBeInTheDocument();
|
||||
expect(mockLegacyRenderer).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
resource: expect.not.objectContaining({ contentType: expect.anything() }),
|
||||
htmlProps: {},
|
||||
supportedContentTypes: ['rawHtml'],
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
|
||||
it.each(['text/html; charset=utf-8', 'TEXT/HTML'])('normalizes HTML MIME type %s', (mimeType) => {
|
||||
const resource: UIResource = {
|
||||
resourceId: 'html-resource',
|
||||
uri: 'ui://html',
|
||||
mimeType,
|
||||
text: '<p>Safe iframe content</p>',
|
||||
};
|
||||
|
||||
render(<UIResourceRenderer resource={resource} />);
|
||||
|
||||
expect(mockLegacyRenderer).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
resource: expect.objectContaining({ mimeType: 'text/html' }),
|
||||
supportedContentTypes: ['rawHtml'],
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
});
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
|
|
@ -45238,6 +45238,16 @@
|
|||
"name": "@librechat/data-schemas",
|
||||
"version": "0.0.68",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mdast-util-directive": "^3.0.0",
|
||||
"mdast-util-from-markdown": "^2.0.1",
|
||||
"mdast-util-gfm": "^3.0.0",
|
||||
"mdast-util-math": "^3.0.0",
|
||||
"micromark-extension-directive": "^3.0.1",
|
||||
"micromark-extension-gfm": "^3.0.0",
|
||||
"micromark-extension-llm-math": "^3.1.0",
|
||||
"micromark-util-decode-string": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/jest": "^29.5.2",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ export default {
|
|||
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!<rootDir>/node_modules/'],
|
||||
coveragePathIgnorePatterns: ['/node_modules/', '/dist/'],
|
||||
testPathIgnorePatterns: ['/node_modules/', '/dist/', '/misc/'],
|
||||
transformIgnorePatterns: [
|
||||
'/node_modules/(?!mdast-util-|micromark|decode-named-character-reference|devlop|longest-streak|unist-util-|zwitch|character-(?:entities|reference)|parse-entities|stringify-entities|is-(?:alphanumerical|alphabetical|decimal|hexadecimal)|ccount|markdown-table|escape-string-regexp)',
|
||||
],
|
||||
coverageReporters: ['text', 'cobertura'],
|
||||
testResultsProcessor: 'jest-junit',
|
||||
moduleNameMapper: {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,16 @@
|
|||
"url": "https://github.com/danny-avila/LibreChat/issues"
|
||||
},
|
||||
"homepage": "https://librechat.ai",
|
||||
"dependencies": {
|
||||
"mdast-util-directive": "^3.0.0",
|
||||
"mdast-util-from-markdown": "^2.0.1",
|
||||
"mdast-util-gfm": "^3.0.0",
|
||||
"mdast-util-math": "^3.0.0",
|
||||
"micromark-extension-directive": "^3.0.1",
|
||||
"micromark-extension-gfm": "^3.0.0",
|
||||
"micromark-extension-llm-math": "^3.1.0",
|
||||
"micromark-util-decode-string": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/jest": "^29.5.2",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { nanoid } from 'nanoid';
|
||||
import mongoose from 'mongoose';
|
||||
import { Constants } from 'librechat-data-provider';
|
||||
import { MongoMemoryServer } from 'mongodb-memory-server';
|
||||
import { Constants, ContentTypes, Tools } from 'librechat-data-provider';
|
||||
import type { SchemaWithMeiliMethods } from '~/models/plugins/mongoMeili';
|
||||
import type * as t from '~/types';
|
||||
import { createShareMethods, anonymizeSharedContent, type ShareMethods } from './share';
|
||||
|
|
@ -521,6 +521,133 @@ describe('Share Methods', () => {
|
|||
).toBe(result?.conversationId);
|
||||
});
|
||||
|
||||
test('strips MCP-UI attachments from public shared messages', async () => {
|
||||
const userId = new mongoose.Types.ObjectId().toString();
|
||||
const conversationId = `conv_${nanoid()}`;
|
||||
const shareId = `share_${nanoid()}`;
|
||||
|
||||
const message = await Message.create({
|
||||
messageId: `msg_${nanoid()}`,
|
||||
conversationId,
|
||||
user: userId,
|
||||
text: '\\ui{malicious}',
|
||||
isCreatedByUser: false,
|
||||
content: [
|
||||
{ type: ContentTypes.TEXT, text: 'Before \\ui{malicious} after' },
|
||||
{ type: ContentTypes.TEXT, text: '`\\ui{literal}`' },
|
||||
{
|
||||
type: ContentTypes.TEXT,
|
||||
text: {
|
||||
value: 'Object \\ui{malicious} value',
|
||||
annotations: [{ type: 'citation' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
subagent_content: [
|
||||
{ type: ContentTypes.TEXT, text: 'Nested \\ui{malicious} content' },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
attachments: [
|
||||
{
|
||||
type: Tools.ui_resources,
|
||||
[Tools.ui_resources]: [
|
||||
{
|
||||
resourceId: 'malicious',
|
||||
mimeType: 'application/vnd.mcp-ui.remote-dom+javascript',
|
||||
text: "root.innerHTML='<img src=x onerror=alert(window.origin)>'",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ type: Tools.web_search, [Tools.web_search]: { results: [] } },
|
||||
],
|
||||
});
|
||||
|
||||
await SharedLink.create({
|
||||
shareId,
|
||||
conversationId,
|
||||
user: userId,
|
||||
messages: [message._id],
|
||||
});
|
||||
|
||||
const result = await shareMethods.getSharedMessages(shareId);
|
||||
|
||||
expect(result?.messages[0].attachments).toHaveLength(1);
|
||||
expect(result?.messages[0].attachments?.[0].type).toBe(Tools.web_search);
|
||||
expect(result?.messages[0].text).toBe('');
|
||||
expect(result?.messages[0].content).toEqual([
|
||||
{ type: ContentTypes.TEXT, text: 'Before after' },
|
||||
{ type: ContentTypes.TEXT, text: '`\\ui{literal}`' },
|
||||
{
|
||||
type: ContentTypes.TEXT,
|
||||
text: { value: 'Object value', annotations: [{ type: 'citation' }] },
|
||||
},
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
subagent_content: [{ type: ContentTypes.TEXT, text: 'Nested content' }],
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test.each([true, null])(
|
||||
'matches text and content renderers for author flag %s in public shares',
|
||||
async (authorFlag) => {
|
||||
const userId = new mongoose.Types.ObjectId().toString();
|
||||
const conversationId = `conv_${nanoid()}`;
|
||||
const shareId = `share_${nanoid()}`;
|
||||
|
||||
const message = await Message.create({
|
||||
messageId: `msg_${nanoid()}`,
|
||||
conversationId,
|
||||
user: userId,
|
||||
text: 'Example: \\ui{literal}',
|
||||
isCreatedByUser: authorFlag,
|
||||
content: [
|
||||
{ type: ContentTypes.TEXT, text: 'Part: \\ui{literal}' },
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
name: Constants.SUBAGENT,
|
||||
output: 'Legacy \\ui{nested} output',
|
||||
subagent_content: [{ type: ContentTypes.TEXT, text: 'Nested \\ui{nested} text' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
attachments: [{ type: Tools.ui_resources, [Tools.ui_resources]: [] }],
|
||||
});
|
||||
await SharedLink.create({
|
||||
shareId,
|
||||
conversationId,
|
||||
user: userId,
|
||||
messages: [message._id],
|
||||
});
|
||||
|
||||
const result = await shareMethods.getSharedMessages(shareId);
|
||||
|
||||
expect(result?.messages[0].text).toBe('Example: \\ui{literal}');
|
||||
expect(result?.messages[0].content).toEqual([
|
||||
{
|
||||
type: ContentTypes.TEXT,
|
||||
text: authorFlag === true ? 'Part: \\ui{literal}' : 'Part: ',
|
||||
},
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
name: Constants.SUBAGENT,
|
||||
output: 'Legacy output',
|
||||
subagent_content: [{ type: ContentTypes.TEXT, text: 'Nested text' }],
|
||||
},
|
||||
},
|
||||
]);
|
||||
expect(result?.messages[0].attachments).toBeUndefined();
|
||||
},
|
||||
);
|
||||
|
||||
test('strips storage-internal fields while preserving shared render data', async () => {
|
||||
const userId = new mongoose.Types.ObjectId().toString();
|
||||
const conversationId = `conv_${nanoid()}`;
|
||||
|
|
@ -741,7 +868,7 @@ describe('Share Methods', () => {
|
|||
expect(share?.fileSnapshots?.map((snapshot) => snapshot.file_id)).toContain('steer-file-2');
|
||||
});
|
||||
|
||||
test('leaves non-steer content untouched (same array reference when no steer part)', () => {
|
||||
test('leaves safe non-steer content untouched (same array reference)', () => {
|
||||
const plainContent = [
|
||||
{ type: 'text', text: 'no steers here' },
|
||||
{ type: 'tool_call', tool_call: { id: 'call_1' } },
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
import { nanoid } from 'nanoid';
|
||||
import { Types } from 'mongoose';
|
||||
import { Constants, ContentTypes, FileSources } from 'librechat-data-provider';
|
||||
import { Constants, ContentTypes, FileSources, Tools } from 'librechat-data-provider';
|
||||
import type { FilterQuery, Model } from 'mongoose';
|
||||
import type { SchemaWithMeiliMethods } from '~/models/plugins/mongoMeili';
|
||||
import type * as t from '~/types';
|
||||
import {
|
||||
sanitizeUIResourceContent,
|
||||
stripMessageUIResourceMarkers,
|
||||
} from '~/utils/stripUIResourceMarkers';
|
||||
import { activeExpirationFilter } from '~/utils/retention';
|
||||
import { isValidObjectIdString } from '~/utils/objectId';
|
||||
import logger from '~/config/winston';
|
||||
|
|
@ -118,6 +122,13 @@ function sanitizeSharedFiles(files: unknown): t.SharedFile[] | undefined {
|
|||
return sanitized.length > 0 ? sanitized : undefined;
|
||||
}
|
||||
|
||||
function sanitizeSharedAttachments(attachments: unknown): t.SharedFile[] | undefined {
|
||||
const sanitized = sanitizeSharedFiles(attachments)?.filter(
|
||||
(attachment) => attachment.type !== Tools.ui_resources,
|
||||
);
|
||||
return sanitized && sanitized.length > 0 ? sanitized : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sources backed by a durable stored object that the share-scoped routes can
|
||||
* stream with only `storageKey`/`filepath` + the request. Sources requiring
|
||||
|
|
@ -379,6 +390,7 @@ export function anonymizeSharedContent(
|
|||
shareId: string;
|
||||
snapshotIds: Set<string>;
|
||||
includeFiles: boolean;
|
||||
sanitizeUIResourceMarkers?: boolean;
|
||||
},
|
||||
): unknown[] | undefined {
|
||||
if (!Array.isArray(content)) {
|
||||
|
|
@ -386,8 +398,13 @@ export function anonymizeSharedContent(
|
|||
}
|
||||
|
||||
let result: unknown[] | null = null;
|
||||
const sanitized = sanitizeUIResourceContent(content, params.sanitizeUIResourceMarkers === true);
|
||||
if (sanitized !== content) {
|
||||
result = sanitized as unknown[];
|
||||
}
|
||||
|
||||
for (let i = 0; i < content.length; i++) {
|
||||
const part = content[i];
|
||||
const part = result?.[i] ?? content[i];
|
||||
if (!isSteerPartWithFiles(part)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -405,9 +422,7 @@ export function anonymizeSharedContent(
|
|||
),
|
||||
)
|
||||
: undefined;
|
||||
if (result == null) {
|
||||
result = [...content];
|
||||
}
|
||||
result ??= [...content];
|
||||
result[i] = files ? { ...rest, files } : rest;
|
||||
}
|
||||
return result ?? content;
|
||||
|
|
@ -456,7 +471,7 @@ function anonymizeMessages(
|
|||
// When files are not shared for this link, omit files/attachments entirely so
|
||||
// viewers can't load them through the owner's original (e.g. static) paths.
|
||||
const attachments = includeFiles
|
||||
? sanitizeSharedFiles(message.attachments)?.map((attachment) =>
|
||||
? sanitizeSharedAttachments(message.attachments)?.map((attachment) =>
|
||||
applyShareFileRoute(
|
||||
{
|
||||
...attachment,
|
||||
|
|
@ -492,13 +507,17 @@ function anonymizeMessages(
|
|||
anonymizeMessageId(message.parentMessageId || ''),
|
||||
conversationId: newConvoId,
|
||||
sender: message.sender,
|
||||
text: message.text,
|
||||
text:
|
||||
message.isCreatedByUser === false
|
||||
? stripMessageUIResourceMarkers(message.text, message.error)
|
||||
: message.text,
|
||||
content: anonymizeSharedContent(message.content, {
|
||||
newConvoId,
|
||||
newMessageId,
|
||||
shareId,
|
||||
snapshotIds,
|
||||
includeFiles,
|
||||
sanitizeUIResourceMarkers: message.isCreatedByUser !== true,
|
||||
}),
|
||||
...(message.iconURL && { iconURL: message.iconURL }),
|
||||
...(model && { model }),
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@ export { tenantSafeBulkWrite } from './tenantBulkWrite';
|
|||
export * from './transactions';
|
||||
export * from './objectId';
|
||||
export * from './yaml';
|
||||
export * from './stripUIResourceMarkers';
|
||||
|
|
|
|||
255
packages/data-schemas/src/utils/stripUIResourceMarkers.spec.ts
Normal file
255
packages/data-schemas/src/utils/stripUIResourceMarkers.spec.ts
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
import { Constants, ContentTypes } from 'librechat-data-provider';
|
||||
import {
|
||||
sanitizeUIResourceContent,
|
||||
stripMessageUIResourceMarkers,
|
||||
stripUIResourceMarkers,
|
||||
} from './stripUIResourceMarkers';
|
||||
|
||||
describe('stripUIResourceMarkers', () => {
|
||||
it('removes markers from renderable text while preserving non-text Markdown nodes', () => {
|
||||
const markdown = [
|
||||
'Before \\ui{rendered} after',
|
||||
'`\\ui{inline}`',
|
||||
'```text',
|
||||
'\\ui{fenced}',
|
||||
'```',
|
||||
'<div>\\ui{html}</div>',
|
||||
'$$\\ui{inline-math}$$',
|
||||
'$$',
|
||||
'\\ui{display-math}',
|
||||
'$$',
|
||||
].join('\n');
|
||||
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(markdown.replace('\\ui{rendered}', ''));
|
||||
});
|
||||
|
||||
it('preserves markers inside inline and display math nodes', () => {
|
||||
const markdown = ['$$\\ui{inline-math}$$', '', '$$', '\\ui{display-math}', '$$'].join('\n');
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(markdown);
|
||||
expect(stripUIResourceMarkers('$\\ui{rendered}$')).toBe('$$');
|
||||
});
|
||||
|
||||
it('preserves directive attributes that the renderer does not visit as text', () => {
|
||||
const markdown = '::artifact{title="\\ui{example}"}';
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(markdown);
|
||||
});
|
||||
|
||||
it('preserves text directive labels replaced before MCP marker rendering', () => {
|
||||
const markdown = ':note[\\ui{directive}] outside \\ui{outside}';
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(':note[\\ui{directive}] outside ');
|
||||
});
|
||||
|
||||
it('removes markers after Markdown escapes and character references are decoded', () => {
|
||||
const markdown = [
|
||||
'Encoded \ui{backslash}',
|
||||
'Encoded \\ui{braces}',
|
||||
'Escaped \\ui\\{braces\\}',
|
||||
].join('\n');
|
||||
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(['Encoded ', 'Encoded ', 'Escaped '].join('\n'));
|
||||
});
|
||||
|
||||
it('removes markers formed by citation cleanup before MCP marker rendering', () => {
|
||||
const markdown = [
|
||||
'Actual \\u\ue206i{actual}',
|
||||
'Literal \\u\\ue206i{literal}',
|
||||
'Entity \\ui{entity}',
|
||||
'Mixed \\u\ue206i{mixed}',
|
||||
].join('\n');
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(
|
||||
['Actual ', 'Literal ', 'Entity ', 'Mixed '].join('\n'),
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves markers inside composite citations consumed before MCP marker rendering', () => {
|
||||
const markdown = '\\ue200\\ue202turn0search0 \\ui{citation}\\ue201 outside \\ui{outside}';
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(
|
||||
'\\ue200\\ue202turn0search0 \\ui{citation}\\ue201 outside ',
|
||||
);
|
||||
expect(stripUIResourceMarkers('\\ue200 invalid \\ui{rendered}\\ue201')).toBe(
|
||||
'\\ue200 invalid \\ue201',
|
||||
);
|
||||
expect(stripUIResourceMarkers('\\ue200\n\\ue202turn0search0 \\ui{rendered}\\ue201')).toBe(
|
||||
'\\ue200\n\\ue202turn0search0 \\ue201',
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves highlighted citation text-node boundaries before MCP marker rendering', () => {
|
||||
const acrossBoundary = '\\u\\ue203i{id}\\ue204';
|
||||
expect(stripUIResourceMarkers(acrossBoundary)).toBe(acrossBoundary);
|
||||
expect(stripUIResourceMarkers('\\ue203\\ui{inside}\\ue204')).toBe('\\ue203\\ue204');
|
||||
expect(
|
||||
stripUIResourceMarkers('\\ue203 text \\ue200\\ue202turn0search0 \\ui{nested}\\ue201\\ue204'),
|
||||
).toBe('\\ue203 text \\ue200\\ue202turn0search0 \\ue201\\ue204');
|
||||
});
|
||||
|
||||
it('uses the earliest citation match when highlight and composite ranges cross', () => {
|
||||
const markdown = '\\ue203 text \\ue200\\ue202turn0search0 \\ui{id}\\ue204 tail \\ue201';
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(
|
||||
'\\ue203 text \\ue200\\ue202turn0search0 \\ue204 tail \\ue201',
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves text boundaries around invalid composite citations', () => {
|
||||
const markdown = '\\u\\ue200\\ue201i{id}';
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(markdown);
|
||||
});
|
||||
|
||||
it('handles many unmatched citation openers in linear time', () => {
|
||||
const markdown = `${'\\ue203'.repeat(16_000)}\\ui{rendered}`;
|
||||
expect(stripUIResourceMarkers(markdown)).toBe('\\ue203'.repeat(16_000));
|
||||
});
|
||||
|
||||
it('preserves markers in message text that bypasses Markdown rendering', () => {
|
||||
expect(stripMessageUIResourceMarkers('Error \\ui{literal}', true)).toBe('Error \\ui{literal}');
|
||||
expect(
|
||||
stripMessageUIResourceMarkers(':::thinking Hidden \\ui{hidden} ::: Visible \\ui{visible}'),
|
||||
).toBe(':::thinking Hidden \\ui{hidden} ::: Visible ');
|
||||
expect(stripMessageUIResourceMarkers('\\u:::thinking Hidden :::i{formed}')).toBe(
|
||||
':::thinking Hidden :::',
|
||||
);
|
||||
expect(stripMessageUIResourceMarkers(':::thinking hidden ::: \\ui{id}')).toBe(
|
||||
':::thinking hidden ::: ',
|
||||
);
|
||||
});
|
||||
|
||||
it('handles paragraph continuations and container code according to CommonMark', () => {
|
||||
const markdown = [
|
||||
'intro',
|
||||
' \\ui{paragraph}',
|
||||
'',
|
||||
' \\ui{indented-code}',
|
||||
'> ```',
|
||||
'> \\ui{quote-code}',
|
||||
'outside \\ui{outside}',
|
||||
].join('\n');
|
||||
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(
|
||||
markdown.replace('\\ui{paragraph}', '').replace('\\ui{outside}', ''),
|
||||
);
|
||||
});
|
||||
|
||||
it('maps markers across CRLF paragraph continuations', () => {
|
||||
const markdown = 'intro\r\n \\ui{paragraph}\r\nnext \\ui{next}';
|
||||
expect(stripUIResourceMarkers(markdown)).toBe('intro\r\n \r\nnext ');
|
||||
});
|
||||
|
||||
it('maps markers across blockquote paragraph prefixes', () => {
|
||||
const markdown = '> intro\n> \\ui{paragraph}\n>\n> \\ui{code}';
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(markdown.replace('\\ui{paragraph}', ''));
|
||||
});
|
||||
|
||||
it('handles escaped blockquote content and CommonMark replacement characters', () => {
|
||||
expect(stripUIResourceMarkers('> intro\n> \\> \\ui{paragraph}')).toBe('> intro\n> \\> ');
|
||||
expect(stripUIResourceMarkers('prefix\0 \\ui{paragraph}')).toBe('prefix\0 ');
|
||||
});
|
||||
|
||||
it('handles long literal text without per-character source-span objects', () => {
|
||||
const markdown = `\\not-a-marker ${'a'.repeat(100_000)} & plain text`;
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(markdown);
|
||||
});
|
||||
|
||||
it('maps many encoded markers with a monotonic source-segment cursor', () => {
|
||||
const markdown = Array.from({ length: 1_000 }, (_, index) => `\ui{id${index}}`).join(' ');
|
||||
expect(stripUIResourceMarkers(markdown)).toBe(' '.repeat(999));
|
||||
});
|
||||
|
||||
it('walks deeply nested Markdown without recursive traversal', () => {
|
||||
const prefix = '> '.repeat(500);
|
||||
expect(stripUIResourceMarkers(`${prefix}\\ui{deep}`)).toBe(prefix);
|
||||
});
|
||||
|
||||
it('recursively sanitizes TextData and subagent content while preserving annotations', () => {
|
||||
const content = [
|
||||
{
|
||||
type: 'tool_call',
|
||||
tool_call: {
|
||||
subagent_content: [
|
||||
{
|
||||
type: ContentTypes.TEXT,
|
||||
text: {
|
||||
value: 'Before \\ui{nested} after',
|
||||
annotations: [{ type: 'citation' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
expect(sanitizeUIResourceContent(content)).toEqual([
|
||||
{
|
||||
type: 'tool_call',
|
||||
tool_call: {
|
||||
subagent_content: [
|
||||
{
|
||||
type: ContentTypes.TEXT,
|
||||
text: { value: 'Before after', annotations: [{ type: 'citation' }] },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('sanitizes deeply nested subagent content without recursive traversal', () => {
|
||||
const depth = 10_000;
|
||||
let nestedContent: unknown[] = [{ type: ContentTypes.TEXT, text: 'Deep \\ui{deep} content' }];
|
||||
for (let i = 0; i < depth; i++) {
|
||||
nestedContent = [
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: { subagent_content: nestedContent },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
let cursor = sanitizeUIResourceContent(nestedContent) as unknown[];
|
||||
for (let i = 0; i < depth; i++) {
|
||||
const part = cursor[0] as { tool_call: { subagent_content: unknown[] } };
|
||||
cursor = part.tool_call.subagent_content;
|
||||
}
|
||||
expect(cursor).toEqual([{ type: ContentTypes.TEXT, text: 'Deep content' }]);
|
||||
});
|
||||
|
||||
it('preserves top-level user text while sanitizing assistant-rendered subagent fields', () => {
|
||||
const content = [
|
||||
{ type: ContentTypes.TEXT, text: 'User example \\ui{literal}' },
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
name: Constants.SUBAGENT,
|
||||
output: 'Legacy \\ui{legacy} output',
|
||||
subagent_content: [
|
||||
{ type: ContentTypes.TEXT, text: 'Nested \\ui{nested} content' },
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
name: Constants.SUBAGENT,
|
||||
output: 'Deep \\ui{deep} output',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
expect(sanitizeUIResourceContent(content, false)).toEqual([
|
||||
{ type: ContentTypes.TEXT, text: 'User example \\ui{literal}' },
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: {
|
||||
name: Constants.SUBAGENT,
|
||||
output: 'Legacy output',
|
||||
subagent_content: [
|
||||
{ type: ContentTypes.TEXT, text: 'Nested content' },
|
||||
{
|
||||
type: ContentTypes.TOOL_CALL,
|
||||
tool_call: { name: Constants.SUBAGENT, output: 'Deep output' },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
599
packages/data-schemas/src/utils/stripUIResourceMarkers.ts
Normal file
599
packages/data-schemas/src/utils/stripUIResourceMarkers.ts
Normal file
|
|
@ -0,0 +1,599 @@
|
|||
import { gfm } from 'micromark-extension-gfm';
|
||||
import { gfmFromMarkdown } from 'mdast-util-gfm';
|
||||
import { mathFromMarkdown } from 'mdast-util-math';
|
||||
import { math } from 'micromark-extension-llm-math';
|
||||
import { fromMarkdown } from 'mdast-util-from-markdown';
|
||||
import { directive } from 'micromark-extension-directive';
|
||||
import { decodeString } from 'micromark-util-decode-string';
|
||||
import { directiveFromMarkdown } from 'mdast-util-directive';
|
||||
import { Constants, ContentTypes } from 'librechat-data-provider';
|
||||
|
||||
const UI_RESOURCE_PATTERN = /\\ui\{[\w]+(?:,[\w]+)*\}/g;
|
||||
const CITATION_CLEANUP = /\\ue20[0-46]|[\ue200-\ue204\ue206]/g;
|
||||
const STANDALONE_SUFFIX = /turn(\d+)(search|image|news|video|ref|file)(\d+)/y;
|
||||
const MARKDOWN_ESCAPE_OR_REFERENCE = /\\(.)|&(#(?:\d{1,7}|[xX][\dA-Fa-f]{1,6})|[\dA-Za-z]{1,31});/g;
|
||||
const TEXT_BOUNDARY = '\0';
|
||||
|
||||
type MarkdownNode = {
|
||||
type: string;
|
||||
position?: { start: { offset?: number }; end: { offset?: number } };
|
||||
children?: MarkdownNode[];
|
||||
};
|
||||
|
||||
type SourceSegment = {
|
||||
decodedStart: number;
|
||||
decodedEnd: number;
|
||||
sourceStart: number;
|
||||
sourceEnd: number;
|
||||
literal: boolean;
|
||||
};
|
||||
|
||||
type CitationToken = {
|
||||
code: number;
|
||||
start: number;
|
||||
end: number;
|
||||
line: number;
|
||||
literal: boolean;
|
||||
};
|
||||
|
||||
type CitationMatch = { start: number; end: number };
|
||||
|
||||
type CitationOutputSegment =
|
||||
| { kind: 'text'; intervals: Array<[number, number]> }
|
||||
| { kind: 'nontext' };
|
||||
|
||||
function collectCitationTokens(value: string) {
|
||||
const tokens: CitationToken[] = [];
|
||||
const allStandalone: CitationMatch[] = [];
|
||||
const standalone: CitationMatch[] = [];
|
||||
let lastCompositeOpen = -1;
|
||||
let lastCompositeClose = -1;
|
||||
let line = 0;
|
||||
|
||||
for (let index = 0; index < value.length; ) {
|
||||
let code = -1;
|
||||
let end = index + 1;
|
||||
let literal = false;
|
||||
const characterCode = value.charCodeAt(index);
|
||||
if (characterCode >= 0xe200 && characterCode <= 0xe206 && characterCode !== 0xe205) {
|
||||
code = characterCode - 0xe200;
|
||||
} else if (
|
||||
value.charCodeAt(index) === 92 &&
|
||||
value.startsWith('ue20', index + 1) &&
|
||||
index + 5 < value.length
|
||||
) {
|
||||
const digit = value.charCodeAt(index + 5) - 48;
|
||||
if (digit >= 0 && digit <= 6 && digit !== 5) {
|
||||
code = digit;
|
||||
end = index + 6;
|
||||
literal = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (code < 0) {
|
||||
if (
|
||||
characterCode === 10 ||
|
||||
characterCode === 13 ||
|
||||
characterCode === 0x2028 ||
|
||||
characterCode === 0x2029
|
||||
) {
|
||||
line++;
|
||||
}
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const token = { code, start: index, end, line, literal };
|
||||
tokens.push(token);
|
||||
if (code === 2) {
|
||||
STANDALONE_SUFFIX.lastIndex = end;
|
||||
const suffix = STANDALONE_SUFFIX.exec(value);
|
||||
if (suffix) {
|
||||
const citation = { start: index, end: STANDALONE_SUFFIX.lastIndex };
|
||||
allStandalone.push(citation);
|
||||
if (lastCompositeOpen === -1 || lastCompositeClose > lastCompositeOpen) {
|
||||
standalone.push(citation);
|
||||
}
|
||||
}
|
||||
} else if (code === 0) {
|
||||
lastCompositeOpen = index;
|
||||
} else if (code === 1) {
|
||||
lastCompositeClose = index;
|
||||
}
|
||||
index = end;
|
||||
}
|
||||
|
||||
return { tokens, allStandalone, standalone };
|
||||
}
|
||||
|
||||
function pairCitationRanges(tokens: CitationToken[], openCode: number, closeCode: number) {
|
||||
const openers = tokens.filter((token) => token.code === openCode);
|
||||
const closers = tokens.filter((token) => token.code === closeCode);
|
||||
const ranges: CitationMatch[] = [];
|
||||
let closeIndex = 0;
|
||||
for (const opener of openers) {
|
||||
while (
|
||||
closers[closeIndex] &&
|
||||
(closers[closeIndex].line < opener.line ||
|
||||
(closers[closeIndex].line === opener.line && closers[closeIndex].start < opener.end))
|
||||
) {
|
||||
closeIndex++;
|
||||
}
|
||||
const closer = closers[closeIndex];
|
||||
if (closer?.line === opener.line) {
|
||||
ranges.push({ start: opener.start, end: closer.end });
|
||||
}
|
||||
}
|
||||
return ranges;
|
||||
}
|
||||
|
||||
/** Model the citation plugin's emitted text nodes without its unbounded wildcard regexes. */
|
||||
function applyCitationTextBoundaries(value: string, sourceSegments: SourceSegment[]) {
|
||||
const { tokens, allStandalone, standalone } = collectCitationTokens(value);
|
||||
const highlighted = pairCitationRanges(tokens, 3, 4);
|
||||
const composite = pairCitationRanges(tokens, 0, 1);
|
||||
const output: CitationOutputSegment[] = [];
|
||||
let tokenIndex = 0;
|
||||
|
||||
const addText = (start: number, end: number, highlightedText = false) => {
|
||||
const intervals: Array<[number, number]> = [];
|
||||
let cursor = start;
|
||||
while (tokens[tokenIndex]?.end <= start) {
|
||||
tokenIndex++;
|
||||
}
|
||||
while (tokens[tokenIndex]?.start < end) {
|
||||
const token = tokens[tokenIndex++];
|
||||
const remove = highlightedText
|
||||
? token.literal && (token.code === 3 || token.code === 4)
|
||||
: true;
|
||||
if (remove) {
|
||||
if (cursor < token.start) {
|
||||
intervals.push([cursor, token.start]);
|
||||
}
|
||||
cursor = token.end;
|
||||
}
|
||||
}
|
||||
if (cursor < end) {
|
||||
intervals.push([cursor, end]);
|
||||
}
|
||||
if (intervals.length > 0 || highlightedText) {
|
||||
output.push({ kind: 'text', intervals });
|
||||
}
|
||||
};
|
||||
|
||||
let highlightedIndex = 0;
|
||||
let compositeIndex = 0;
|
||||
let standaloneIndex = 0;
|
||||
let compositeCitationIndex = 0;
|
||||
let position = 0;
|
||||
while (position < value.length) {
|
||||
while (highlighted[highlightedIndex]?.start < position) {
|
||||
highlightedIndex++;
|
||||
}
|
||||
while (composite[compositeIndex]?.start < position) {
|
||||
compositeIndex++;
|
||||
}
|
||||
while (standalone[standaloneIndex]?.start < position) {
|
||||
standaloneIndex++;
|
||||
}
|
||||
|
||||
const highlightedMatch = highlighted[highlightedIndex];
|
||||
const compositeMatch = composite[compositeIndex];
|
||||
const standaloneMatch = standalone[standaloneIndex];
|
||||
let type: 'highlighted' | 'composite' | 'standalone' | undefined;
|
||||
let next = highlightedMatch;
|
||||
if (next) {
|
||||
type = 'highlighted';
|
||||
}
|
||||
if (compositeMatch && (!next || compositeMatch.start < next.start)) {
|
||||
type = 'composite';
|
||||
next = compositeMatch;
|
||||
}
|
||||
if (standaloneMatch && (!next || standaloneMatch.start < next.start)) {
|
||||
type = 'standalone';
|
||||
next = standaloneMatch;
|
||||
}
|
||||
if (!next || !type) {
|
||||
addText(position, value.length);
|
||||
break;
|
||||
}
|
||||
|
||||
if (next.start > position) {
|
||||
addText(position, next.start);
|
||||
}
|
||||
if (type === 'highlighted') {
|
||||
addText(next.start, next.end, true);
|
||||
highlightedIndex++;
|
||||
} else if (type === 'standalone') {
|
||||
output.push({ kind: 'nontext' });
|
||||
standaloneIndex++;
|
||||
} else {
|
||||
while (allStandalone[compositeCitationIndex]?.start < next.start) {
|
||||
compositeCitationIndex++;
|
||||
}
|
||||
const citation = allStandalone[compositeCitationIndex];
|
||||
if (citation && citation.end <= next.end) {
|
||||
output.push({ kind: 'nontext' });
|
||||
}
|
||||
compositeIndex++;
|
||||
}
|
||||
position = next.end;
|
||||
}
|
||||
|
||||
if (output.length === 0) {
|
||||
tokenIndex = 0;
|
||||
addText(0, value.length);
|
||||
}
|
||||
|
||||
let transformedValue = '';
|
||||
const transformedSegments: SourceSegment[] = [];
|
||||
let sourceSegmentIndex = 0;
|
||||
const appendInterval = ([start, end]: [number, number]) => {
|
||||
while (sourceSegments[sourceSegmentIndex]?.decodedEnd <= start) {
|
||||
sourceSegmentIndex++;
|
||||
}
|
||||
let index = sourceSegmentIndex;
|
||||
while (sourceSegments[index]?.decodedStart < end) {
|
||||
const segment = sourceSegments[index];
|
||||
const sliceStart = Math.max(start, segment.decodedStart);
|
||||
const sliceEnd = Math.min(end, segment.decodedEnd);
|
||||
if (sliceStart < sliceEnd) {
|
||||
const decodedStart = transformedValue.length;
|
||||
transformedValue += value.slice(sliceStart, sliceEnd);
|
||||
const sourceStart = segment.literal
|
||||
? segment.sourceStart + sliceStart - segment.decodedStart
|
||||
: segment.sourceStart;
|
||||
const sourceEnd = segment.literal
|
||||
? segment.sourceStart + sliceEnd - segment.decodedStart
|
||||
: segment.sourceEnd;
|
||||
const previous = transformedSegments[transformedSegments.length - 1];
|
||||
if (
|
||||
segment.literal &&
|
||||
previous?.literal &&
|
||||
previous.decodedEnd === decodedStart &&
|
||||
previous.sourceEnd === sourceStart
|
||||
) {
|
||||
previous.decodedEnd = transformedValue.length;
|
||||
previous.sourceEnd = sourceEnd;
|
||||
} else {
|
||||
transformedSegments.push({
|
||||
decodedStart,
|
||||
decodedEnd: transformedValue.length,
|
||||
sourceStart,
|
||||
sourceEnd,
|
||||
literal: segment.literal,
|
||||
});
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
sourceSegmentIndex = Math.max(sourceSegmentIndex, index - 1);
|
||||
};
|
||||
|
||||
output.forEach((segment, index) => {
|
||||
if (index > 0) {
|
||||
transformedValue += TEXT_BOUNDARY;
|
||||
}
|
||||
if (segment.kind === 'text') {
|
||||
segment.intervals.forEach(appendInterval);
|
||||
}
|
||||
});
|
||||
return { value: transformedValue, segments: transformedSegments };
|
||||
}
|
||||
|
||||
function decodeTextWithSourceSpans(source: string) {
|
||||
let value = '';
|
||||
const segments: SourceSegment[] = [];
|
||||
let cursor = 0;
|
||||
MARKDOWN_ESCAPE_OR_REFERENCE.lastIndex = 0;
|
||||
|
||||
const appendLiteral = (start: number, end: number) => {
|
||||
if (start === end) {
|
||||
return;
|
||||
}
|
||||
const decodedStart = value.length;
|
||||
value += source.slice(start, end);
|
||||
const previous = segments[segments.length - 1];
|
||||
if (previous?.literal && previous.decodedEnd === decodedStart && previous.sourceEnd === start) {
|
||||
previous.decodedEnd = value.length;
|
||||
previous.sourceEnd = end;
|
||||
return;
|
||||
}
|
||||
segments.push({
|
||||
decodedStart,
|
||||
decodedEnd: value.length,
|
||||
sourceStart: start,
|
||||
sourceEnd: end,
|
||||
literal: true,
|
||||
});
|
||||
};
|
||||
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = MARKDOWN_ESCAPE_OR_REFERENCE.exec(source)) != null) {
|
||||
appendLiteral(cursor, match.index);
|
||||
const decoded = decodeString(match[0]);
|
||||
if (decoded === match[0]) {
|
||||
appendLiteral(match.index, MARKDOWN_ESCAPE_OR_REFERENCE.lastIndex);
|
||||
} else {
|
||||
const decodedStart = value.length;
|
||||
value += decoded;
|
||||
segments.push({
|
||||
decodedStart,
|
||||
decodedEnd: value.length,
|
||||
sourceStart: match.index,
|
||||
sourceEnd: MARKDOWN_ESCAPE_OR_REFERENCE.lastIndex,
|
||||
literal: false,
|
||||
});
|
||||
}
|
||||
cursor = MARKDOWN_ESCAPE_OR_REFERENCE.lastIndex;
|
||||
}
|
||||
appendLiteral(cursor, source.length);
|
||||
return applyCitationTextBoundaries(value, segments);
|
||||
}
|
||||
|
||||
function mapDecodedRange(
|
||||
segments: SourceSegment[],
|
||||
decodedStart: number,
|
||||
decodedEnd: number,
|
||||
fromIndex: number,
|
||||
): { range: [number, number]; segmentIndex: number } | null {
|
||||
let firstIndex = fromIndex;
|
||||
while (segments[firstIndex]?.decodedEnd <= decodedStart) {
|
||||
firstIndex++;
|
||||
}
|
||||
const first = segments[firstIndex];
|
||||
if (!first || decodedStart < first.decodedStart) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let lastIndex = firstIndex;
|
||||
while (segments[lastIndex]?.decodedEnd < decodedEnd) {
|
||||
lastIndex++;
|
||||
}
|
||||
const last = segments[lastIndex];
|
||||
if (!last || decodedEnd <= last.decodedStart) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const sourceStart = first.literal
|
||||
? first.sourceStart + decodedStart - first.decodedStart
|
||||
: first.sourceStart;
|
||||
const sourceEnd = last.literal
|
||||
? last.sourceStart + decodedEnd - last.decodedStart
|
||||
: last.sourceEnd;
|
||||
return { range: [sourceStart, sourceEnd], segmentIndex: lastIndex };
|
||||
}
|
||||
|
||||
function collectMarkerRanges(root: MarkdownNode, source: string, ranges: Array<[number, number]>) {
|
||||
const stack = [root];
|
||||
while (stack.length > 0) {
|
||||
const node = stack.pop() as MarkdownNode;
|
||||
const start = node.position?.start.offset;
|
||||
const end = node.position?.end.offset;
|
||||
if (node.type === 'text' && start != null && end != null) {
|
||||
const decoded = decodeTextWithSourceSpans(source.slice(start, end));
|
||||
UI_RESOURCE_PATTERN.lastIndex = 0;
|
||||
let segmentCursor = 0;
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = UI_RESOURCE_PATTERN.exec(decoded.value)) != null) {
|
||||
const mapped = mapDecodedRange(
|
||||
decoded.segments,
|
||||
match.index,
|
||||
match.index + match[0].length,
|
||||
segmentCursor,
|
||||
);
|
||||
if (mapped) {
|
||||
segmentCursor = mapped.segmentIndex;
|
||||
ranges.push([start + mapped.range[0], start + mapped.range[1]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.type === 'textDirective') {
|
||||
continue;
|
||||
}
|
||||
if (node.children) {
|
||||
for (let i = node.children.length - 1; i >= 0; i--) {
|
||||
stack.push(node.children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findUIResourceMarkerRanges(text: string): Array<[number, number]> {
|
||||
if (
|
||||
(!text.includes('\\') && !text.includes('&')) ||
|
||||
!decodeString(text).replace(CITATION_CLEANUP, '').includes('\\ui{')
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
const ranges: Array<[number, number]> = [];
|
||||
collectMarkerRanges(
|
||||
fromMarkdown(text, {
|
||||
extensions: [gfm(), directive(), math({ singleDollarTextMath: false })],
|
||||
mdastExtensions: [gfmFromMarkdown(), directiveFromMarkdown(), mathFromMarkdown()],
|
||||
}) as unknown as MarkdownNode,
|
||||
text,
|
||||
ranges,
|
||||
);
|
||||
return ranges;
|
||||
}
|
||||
|
||||
function removeSourceRanges(text: string, ranges: Array<[number, number]>) {
|
||||
let result = '';
|
||||
let cursor = 0;
|
||||
for (const [start, end] of ranges) {
|
||||
result += text.slice(cursor, start);
|
||||
cursor = end;
|
||||
}
|
||||
return result + text.slice(cursor);
|
||||
}
|
||||
|
||||
/** Remove MCP-UI markers only from Markdown text nodes visited by the renderer plugin. */
|
||||
export function stripUIResourceMarkers(text: string): string;
|
||||
export function stripUIResourceMarkers(text: undefined): undefined;
|
||||
export function stripUIResourceMarkers(text: string | undefined): string | undefined;
|
||||
export function stripUIResourceMarkers(text: string | undefined): string | undefined {
|
||||
if (text == null) {
|
||||
return text;
|
||||
}
|
||||
const ranges = findUIResourceMarkerRanges(text);
|
||||
return ranges.length === 0 ? text : removeSourceRanges(text, ranges);
|
||||
}
|
||||
|
||||
/** Sanitize only the portion of a legacy message that the client renders as Markdown. */
|
||||
export function stripMessageUIResourceMarkers(
|
||||
text: string | undefined,
|
||||
error?: unknown,
|
||||
): string | undefined {
|
||||
if (text == null || error) {
|
||||
return text;
|
||||
}
|
||||
const thinkingMatch = /:::thinking[\s\S]*?:::/.exec(text);
|
||||
if (!thinkingMatch) {
|
||||
return stripUIResourceMarkers(text);
|
||||
}
|
||||
const start = thinkingMatch.index;
|
||||
const end = start + thinkingMatch[0].length;
|
||||
const regularContent = text.slice(0, start) + text.slice(end);
|
||||
const renderedStart = regularContent.length - regularContent.trimStart().length;
|
||||
const renderedEnd = regularContent.trimEnd().length;
|
||||
const regularRanges = findUIResourceMarkerRanges(
|
||||
regularContent.slice(renderedStart, renderedEnd),
|
||||
);
|
||||
if (regularRanges.length === 0) {
|
||||
return text;
|
||||
}
|
||||
const sourceRanges: Array<[number, number]> = [];
|
||||
const blockLength = end - start;
|
||||
for (const renderedRange of regularRanges) {
|
||||
const rangeStart = renderedRange[0] + renderedStart;
|
||||
const rangeEnd = renderedRange[1] + renderedStart;
|
||||
if (rangeEnd <= start) {
|
||||
sourceRanges.push([rangeStart, rangeEnd]);
|
||||
} else if (rangeStart >= start) {
|
||||
sourceRanges.push([rangeStart + blockLength, rangeEnd + blockLength]);
|
||||
} else {
|
||||
sourceRanges.push([rangeStart, start], [end, rangeEnd + blockLength]);
|
||||
}
|
||||
}
|
||||
return removeSourceRanges(text, sourceRanges);
|
||||
}
|
||||
|
||||
function sanitizeTextPart(part: Record<string, unknown>): unknown {
|
||||
if (typeof part.text === 'string') {
|
||||
const text = stripUIResourceMarkers(part.text);
|
||||
return text === part.text ? part : { ...part, text };
|
||||
}
|
||||
if (part.text != null && typeof part.text === 'object') {
|
||||
const textData = part.text as Record<string, unknown>;
|
||||
if (typeof textData.value === 'string') {
|
||||
const value = stripUIResourceMarkers(textData.value);
|
||||
return value === textData.value ? part : { ...part, text: { ...textData, value } };
|
||||
}
|
||||
}
|
||||
return part;
|
||||
}
|
||||
|
||||
type ContentFrame = {
|
||||
content: unknown[];
|
||||
sanitizeTextParts: boolean;
|
||||
index: number;
|
||||
result: unknown[] | null;
|
||||
onComplete: (content: unknown[]) => void;
|
||||
};
|
||||
|
||||
function updateFramePart(
|
||||
frame: ContentFrame,
|
||||
index: number,
|
||||
originalPart: unknown,
|
||||
sanitizedPart: unknown,
|
||||
) {
|
||||
if (sanitizedPart === originalPart) {
|
||||
return;
|
||||
}
|
||||
frame.result ??= [...frame.content];
|
||||
frame.result[index] = sanitizedPart;
|
||||
}
|
||||
|
||||
/** Sanitize assistant text parts, including arbitrarily nested persisted subagent content. */
|
||||
export function sanitizeUIResourceContent(content: unknown, sanitizeTextParts = true): unknown {
|
||||
if (!Array.isArray(content)) {
|
||||
return content;
|
||||
}
|
||||
|
||||
let sanitizedContent = content;
|
||||
const stack: ContentFrame[] = [
|
||||
{
|
||||
content,
|
||||
sanitizeTextParts,
|
||||
index: 0,
|
||||
result: null,
|
||||
onComplete: (result) => {
|
||||
sanitizedContent = result;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
while (stack.length > 0) {
|
||||
const frame = stack[stack.length - 1];
|
||||
if (frame.index >= frame.content.length) {
|
||||
stack.pop();
|
||||
frame.onComplete(frame.result ?? frame.content);
|
||||
continue;
|
||||
}
|
||||
|
||||
const index = frame.index++;
|
||||
const part = frame.content[index];
|
||||
if (part == null || typeof part !== 'object') {
|
||||
continue;
|
||||
}
|
||||
|
||||
let sanitizedPart: unknown = part;
|
||||
const record = part as Record<string, unknown>;
|
||||
if (frame.sanitizeTextParts && record.type === ContentTypes.TEXT) {
|
||||
sanitizedPart = sanitizeTextPart(record);
|
||||
}
|
||||
|
||||
const current = sanitizedPart as Record<string, unknown>;
|
||||
if (current.tool_call == null || typeof current.tool_call !== 'object') {
|
||||
updateFramePart(frame, index, part, sanitizedPart);
|
||||
continue;
|
||||
}
|
||||
|
||||
const toolCall = current.tool_call as Record<string, unknown>;
|
||||
let sanitizedToolCall = toolCall;
|
||||
if (toolCall.name === Constants.SUBAGENT && typeof toolCall.output === 'string') {
|
||||
const output = stripUIResourceMarkers(toolCall.output);
|
||||
if (output !== toolCall.output) {
|
||||
sanitizedToolCall = { ...sanitizedToolCall, output };
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(toolCall.subagent_content)) {
|
||||
const originalSubagentContent = toolCall.subagent_content;
|
||||
stack.push({
|
||||
content: originalSubagentContent,
|
||||
sanitizeTextParts: true,
|
||||
index: 0,
|
||||
result: null,
|
||||
onComplete: (subagentContent) => {
|
||||
if (subagentContent !== originalSubagentContent) {
|
||||
sanitizedToolCall = { ...sanitizedToolCall, subagent_content: subagentContent };
|
||||
}
|
||||
if (sanitizedToolCall !== toolCall) {
|
||||
sanitizedPart = { ...current, tool_call: sanitizedToolCall };
|
||||
}
|
||||
updateFramePart(frame, index, part, sanitizedPart);
|
||||
},
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sanitizedToolCall !== toolCall) {
|
||||
sanitizedPart = { ...current, tool_call: sanitizedToolCall };
|
||||
}
|
||||
updateFramePart(frame, index, part, sanitizedPart);
|
||||
}
|
||||
|
||||
return sanitizedContent;
|
||||
}
|
||||
|
|
@ -1,6 +1,11 @@
|
|||
import path from 'node:path';
|
||||
import { defineConfig } from 'tsdown';
|
||||
|
||||
const isMarkdownParserDependency = (id) =>
|
||||
/^(?:mdast-util-|micromark(?:-|$)|decode-named-character-reference$|devlop$|longest-streak$|unist-util-|zwitch$|character-(?:entities|reference)(?:-|$)|parse-entities$|stringify-entities$|is-(?:alphanumerical|alphabetical|decimal|hexadecimal)$|ccount$|markdown-table$|escape-string-regexp$)/.test(
|
||||
id,
|
||||
);
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts', 'src/admin/capabilities.ts'],
|
||||
format: ['esm', 'cjs'],
|
||||
|
|
@ -10,13 +15,15 @@ export default defineConfig({
|
|||
sourcemap: true,
|
||||
// Warn on module cycles at build time; CI enforces via config/circular-deps.mjs.
|
||||
checks: { circularDependency: true },
|
||||
// Externalize all third-party deps (consumers provide the peers); bundle only `dotenv`
|
||||
// so the package stays self-contained for its env-loading side effect, matching the
|
||||
// prior Rollup build. `neverBundle` is the 0.22 replacement for the deprecated `external`.
|
||||
// Externalize third-party deps consumers provide, while bundling `dotenv` for its
|
||||
// env-loading side effect and the ESM-only Markdown parser for CommonJS consumers.
|
||||
// `neverBundle` is the 0.22 replacement for the deprecated `external`.
|
||||
deps: {
|
||||
alwaysBundle: isMarkdownParserDependency,
|
||||
neverBundle: (id) =>
|
||||
id !== 'dotenv' &&
|
||||
!id.startsWith('dotenv/') &&
|
||||
!isMarkdownParserDependency(id) &&
|
||||
!id.startsWith('.') &&
|
||||
!id.startsWith('~') &&
|
||||
!path.isAbsolute(id),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue